/*
 * Copyright (c) 1999-2018 Douglas Gilbert.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the BSD_LICENSE file.
 */

/*
 * CONTENTS
 *    Some SCSI commands are executed in many contexts and hence began
 *    to appear in several sg3_utils utilities. This files centralizes
 *    some of the low level command execution code. In most cases the
 *    interpretation of the command response is left to the each
 *    utility.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_pt.h"
#include "sg_unaligned.h"

/* Needs to be after config.h */
#ifdef SG_LIB_LINUX
#include <errno.h>
#endif


static const char * const version_str = "1.83 20180204";


#define SENSE_BUFF_LEN 64       /* Arbitrary, could be larger */
#define EBUFF_SZ 256

#define DEF_PT_TIMEOUT 60       /* 60 seconds */
#define START_PT_TIMEOUT 120    /* 120 seconds == 2 minutes */
#define LONG_PT_TIMEOUT 7200    /* 7,200 seconds == 120 minutes */

#define INQUIRY_CMD     0x12
#define INQUIRY_CMDLEN  6
#define REQUEST_SENSE_CMD 0x3
#define REQUEST_SENSE_CMDLEN 6
#define REPORT_LUNS_CMD 0xa0
#define REPORT_LUNS_CMDLEN 12
#define TUR_CMD  0x0
#define TUR_CMDLEN  6

#define SAFE_STD_INQ_RESP_LEN 36 /* other lengths lock up some devices */


const char *
sg_cmds_version()
{
    return version_str;
}

#if defined(__GNUC__) || defined(__clang__)
static int pr2ws(const char * fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
#else
static int pr2ws(const char * fmt, ...);
#endif


static int
pr2ws(const char * fmt, ...)
{
    va_list args;
    int n;

    va_start(args, fmt);
    n = vfprintf(sg_warnings_strm ? sg_warnings_strm : stderr, fmt, args);
    va_end(args);
    return n;
}

/* 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);
}

/* Returns file descriptor >= 0 if successful. If error in Unix returns
   negated errno. */
int
sg_cmds_open_flags(const char * device_name, int flags, int verbose)
{
    return scsi_pt_open_flags(device_name, flags, verbose);
}

/* Returns 0 if successful. If error in Unix returns negated errno. */
int
sg_cmds_close_device(int device_fd)
{
    return scsi_pt_close_device(device_fd);
}

static const char * const pass_through_s = "pass-through";

static int
sg_cmds_process_helper(const char * leadin, int mx_di_len, int resid,
                       const unsigned char * sbp, int slen, bool noisy,
                       int verbose, int * o_sense_cat)
{
    int scat, got;
    bool n = false;
    bool check_data_in = false;
    char b[512];

    scat = sg_err_category_sense(sbp, slen);
    switch (scat) {
    case SG_LIB_CAT_NOT_READY:
    case SG_LIB_CAT_INVALID_OP:
    case SG_LIB_CAT_ILLEGAL_REQ:
    case SG_LIB_CAT_ABORTED_COMMAND:
    case SG_LIB_CAT_COPY_ABORTED:
    case SG_LIB_CAT_DATA_PROTECT:
    case SG_LIB_CAT_PROTECTION:
    case SG_LIB_CAT_NO_SENSE:
    case SG_LIB_CAT_MISCOMPARE:
        n = false;
        break;
    case SG_LIB_CAT_RECOVERED:
    case SG_LIB_CAT_MEDIUM_HARD:
        check_data_in = true;
#if defined(__GNUC__)
#if (__GNUC__ >= 7)
        __attribute__((fallthrough));
        /* FALL THROUGH */
#endif
#endif
    case SG_LIB_CAT_UNIT_ATTENTION:
    case SG_LIB_CAT_SENSE:
    default:
        n = noisy;
        break;
    }
    if (verbose || n) {
        if (leadin && (strlen(leadin) > 0))
            pr2ws("%s:\n", leadin);
        sg_get_sense_str(NULL, sbp, slen, (verbose > 1),
                         sizeof(b), b);
        pr2ws("%s", b);
        if ((mx_di_len > 0) && (resid > 0)) {
            got = mx_di_len - resid;
            if ((verbose > 2) || check_data_in || (got > 0))
                pr2ws("    %s requested %d bytes (data-in) but got %d "
                      "bytes\n", pass_through_s, mx_di_len, got);
        }
    }
    if (o_sense_cat)
        *o_sense_cat = scat;
    return -2;
}

/* This is a helper function used by sg_cmds_* implementations after the
 * call to the pass-through. pt_res is returned from do_scsi_pt(). If valid
 * sense data is found it is decoded and output to sg_warnings_strm (def:
 * stderr); depending on the 'noisy' and 'verbose' settings. Returns -2 for
 * "sense" category (may not be fatal), -1 for failed, 0, or a positive
 * number. If 'mx_di_len > 0' then asks pass-through for resid and returns
 * (mx_di_len - resid); otherwise returns 0. So for data-in it should return
 * the actual number of bytes received. For data-out (to device) or no data
 * call with 'mx_di_len' set to 0 or less. If -2 returned then sense category
 * output via 'o_sense_cat' pointer (if not NULL). Note that several sense
 * categories also have data in bytes received; -2 is still returned. */
int
sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin,
                     int pt_res, int mx_di_len, const unsigned char * sbp,
                     bool noisy, int verbose, int * o_sense_cat)
{
    int got, cat, duration, slen, resid, resp_code, sstat;
    bool transport_sense;
    char b[1024];

    if (NULL == leadin)
        leadin = "";
    if (pt_res < 0) {
#ifdef SG_LIB_LINUX
        if (verbose)
            pr2ws("%s: %s os error: %s\n", leadin, pass_through_s,
                  safe_strerror(-pt_res));
        if ((-ENXIO == pt_res) && o_sense_cat) {
            if (verbose > 2)
                pr2ws("map ENXIO to SG_LIB_CAT_NOT_READY\n");
            *o_sense_cat = SG_LIB_CAT_NOT_READY;
            return -2;
        } else if (noisy && (0 == verbose))
            pr2ws("%s: %s os error: %s\n", leadin, pass_through_s,
                  safe_strerror(-pt_res));
#else
        if (noisy || verbose)
            pr2ws("%s: %s os error: %s\n", leadin, pass_through_s,
                  safe_strerror(-pt_res));
#endif
        return -1;
    } else if (SCSI_PT_DO_BAD_PARAMS == pt_res) {
        pr2ws("%s: bad %s setup\n", leadin, pass_through_s);
        return -1;
    } else if (SCSI_PT_DO_TIMEOUT == pt_res) {
        pr2ws("%s: %s timeout\n", leadin, pass_through_s);
        return -1;
    }
    if ((verbose > 2) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
        pr2ws("      duration=%d ms\n", duration);
    resid = (mx_di_len > 0) ? get_scsi_pt_resid(ptvp) : 0;
    slen = get_scsi_pt_sense_len(ptvp);
    switch ((cat = get_scsi_pt_result_category(ptvp))) {
    case SCSI_PT_RESULT_GOOD:
        if (sbp && (slen > 7)) {
            resp_code = sbp[0] & 0x7f;
            /* SBC referrals can have status=GOOD and sense_key=COMPLETED */
            if (resp_code >= 0x70) {
                if (resp_code < 0x72) {
                    if (SPC_SK_NO_SENSE != (0xf & sbp[2]))
                        sg_err_category_sense(sbp, slen);
                } else if (resp_code < 0x74) {
                    if (SPC_SK_NO_SENSE != (0xf & sbp[1]))
                        sg_err_category_sense(sbp, slen);
                }
            }
        }
        if (mx_di_len > 0) {
            got = mx_di_len - resid;
            if ((verbose > 1) && (resid != 0))
                pr2ws("    %s: %s requested %d bytes (data-in) but got %d "
                      "bytes\n", leadin, pass_through_s, mx_di_len, got);
            if (got >= 0)
                return got;
            else {
                if (verbose)
                    pr2ws("    %s: %s can't get negative bytes, say it got "
                          "none\n", leadin, pass_through_s);
                return 0;
            }
        } else
            return 0;
    case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
        sstat = get_scsi_pt_status_response(ptvp);
        if (o_sense_cat) {
            switch (sstat) {
            case SAM_STAT_RESERVATION_CONFLICT:
                *o_sense_cat = SG_LIB_CAT_RES_CONFLICT;
                return -2;
            case SAM_STAT_CONDITION_MET:
                *o_sense_cat = SG_LIB_CAT_CONDITION_MET;
                return -2;
            case SAM_STAT_BUSY:
                *o_sense_cat = SG_LIB_CAT_BUSY;
                return -2;
            case SAM_STAT_TASK_SET_FULL:
                *o_sense_cat = SG_LIB_CAT_TS_FULL;
                return -2;
            case SAM_STAT_ACA_ACTIVE:
                *o_sense_cat = SG_LIB_CAT_ACA_ACTIVE;
                return -2;
            case SAM_STAT_TASK_ABORTED:
                *o_sense_cat = SG_LIB_CAT_TASK_ABORTED;
                return -2;
            default:
                break;
            }
        }
        if (verbose || noisy) {
            sg_get_scsi_status_str(sstat, sizeof(b), b);
            pr2ws("%s: scsi status: %s\n", leadin, b);
        }
        return -1;
    case SCSI_PT_RESULT_SENSE:
        return sg_cmds_process_helper(leadin, mx_di_len, resid, sbp, slen,
                                      noisy, verbose, o_sense_cat);
    case SCSI_PT_RESULT_TRANSPORT_ERR:
        if (verbose || noisy) {
            get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
            pr2ws("%s: transport: %s\n", leadin, b);
        }
#ifdef SG_LIB_LINUX
        transport_sense = (slen > 0);
#else
        transport_sense = ((SAM_STAT_CHECK_CONDITION ==
                            get_scsi_pt_status_response(ptvp)) && (slen > 0));
#endif
        if (transport_sense)
            return sg_cmds_process_helper(leadin, mx_di_len, resid, sbp,
                                          slen, noisy, verbose, o_sense_cat);
        else
            return -1;
    case SCSI_PT_RESULT_OS_ERR:
        if (verbose || noisy) {
            get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
            pr2ws("%s: os: %s\n", leadin, b);
        }
        return -1;
    default:
        pr2ws("%s: unknown %s result category (%d)\n", leadin, pass_through_s,
               cat);
        return -1;
    }
}

bool
sg_cmds_is_nvme(const struct sg_pt_base * ptvp)
{
    return pt_device_is_nvme(ptvp);
}

static struct sg_pt_base *
create_pt_obj(const char * cname)
{
    struct sg_pt_base * ptvp = construct_scsi_pt_obj();
    if (NULL == ptvp)
        pr2ws("%s: out of memory\n", cname);
    return ptvp;
}

static const char * const inquiry_s = "inquiry";

static int
sg_ll_inquiry_com(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp,
                  int mx_resp_len, int timeout_secs, int * residp,
                  bool noisy, int verbose)
{
    int res, ret, k, sense_cat, resid;
    unsigned char inq_cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0};
    unsigned char sense_b[SENSE_BUFF_LEN];
    unsigned char * up;
    struct sg_pt_base * ptvp;

    if (cmddt)
        inq_cdb[1] |= 0x2;
    if (evpd)
        inq_cdb[1] |= 0x1;
    inq_cdb[2] = (unsigned char)pg_op;
    /* 16 bit allocation length (was 8, increased in spc3r09, 200209) */
    sg_put_unaligned_be16((uint16_t)mx_resp_len, inq_cdb + 3);
    if (verbose) {
        pr2ws("    %s cdb: ", inquiry_s);
        for (k = 0; k < INQUIRY_CMDLEN; ++k)
            pr2ws("%02x ", inq_cdb[k]);
        pr2ws("\n");
    }
    if (resp && (mx_resp_len > 0)) {
        up = (unsigned char *)resp;
        up[0] = 0x7f;   /* defensive prefill */
        if (mx_resp_len > 4)
            up[4] = 0;
    }
    if (timeout_secs <= 0)
        timeout_secs = DEF_PT_TIMEOUT;
    ptvp = construct_scsi_pt_obj();
    if (NULL == ptvp) {
        pr2ws("%s: out of memory\n", __func__);
        if (residp)
            *residp = 0;
        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, (unsigned char *)resp, mx_resp_len);
    res = do_scsi_pt(ptvp, sg_fd, timeout_secs, verbose);
    ret = sg_cmds_process_resp(ptvp, inquiry_s, res, mx_resp_len, sense_b,
                               noisy, verbose, &sense_cat);
    resid = get_scsi_pt_resid(ptvp);
    if (residp)
        *residp = resid;
    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 if (ret < 4) {
        if (verbose)
            pr2ws("%s: got too few bytes (%d)\n", __func__, ret);
        ret = SG_LIB_CAT_MALFORMED;
    } else
        ret = 0;
    destruct_scsi_pt_obj(ptvp);

    if (resid > 0) {
        if (resid > mx_resp_len) {
            pr2ws("%s resid (%d) should never exceed requested "
                    "len=%d\n", inquiry_s, resid, mx_resp_len);
            return ret ? ret : SG_LIB_CAT_MALFORMED;
        }
        /* zero unfilled section of response buffer, based on resid */
        memset((unsigned char *)resp + (mx_resp_len - resid), 0, resid);
    }
    return ret;
}

/* Invokes a SCSI INQUIRY command and yields the response. Returns 0 when
 * successful, various SG_LIB_CAT_* positive values or -1 -> other errors.
 * The CMDDT field is obsolete in the INQUIRY cdb. */
int
sg_ll_inquiry(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp,
              int mx_resp_len, bool noisy, int verbose)
{
    return sg_ll_inquiry_com(sg_fd, cmddt, evpd, pg_op, resp, mx_resp_len,
                             0 /* timeout_sec */, NULL, noisy, verbose);
}

/* Yields most of first 36 bytes of a standard INQUIRY (evpd==0) response.
 * Returns 0 when successful, various SG_LIB_CAT_* positive values or
 * -1 -> other errors */
int
sg_simple_inquiry(int sg_fd, struct sg_simple_inquiry_resp * inq_data,
                  bool noisy, int verbose)
{
    int ret;
    unsigned char inq_resp[SAFE_STD_INQ_RESP_LEN];

    if (inq_data) {
        memset(inq_data, 0, sizeof(* inq_data));
        inq_data->peripheral_qualifier = 0x3;
        inq_data->peripheral_type = 0x1f;
    }
    ret = sg_ll_inquiry_com(sg_fd, false, false, 0, inq_resp,
                            sizeof(inq_resp), 0, NULL, noisy, verbose);

    if (inq_data && (0 == ret)) {
        inq_data->peripheral_qualifier = (inq_resp[0] >> 5) & 0x7;
        inq_data->peripheral_type = inq_resp[0] & 0x1f;
        inq_data->byte_1 = inq_resp[1];
        inq_data->version = inq_resp[2];
        inq_data->byte_3 = inq_resp[3];
        inq_data->byte_5 = inq_resp[5];
        inq_data->byte_6 = inq_resp[6];
        inq_data->byte_7 = inq_resp[7];
        memcpy(inq_data->vendor, inq_resp + 8, 8);
        memcpy(inq_data->product, inq_resp + 16, 16);
        memcpy(inq_data->revision, inq_resp + 32, 4);
    }
    return ret;
}

/* Invokes a SCSI INQUIRY command and yields the response. Returns 0 when
 * successful, various SG_LIB_CAT_* positive values or -1 -> other errors.
 * The CMDDT field is obsolete in the INQUIRY cdb (since spc3r16 in 2003) so
 * an argument to set it has been removed (use the REPORT SUPPORTED OPERATION
 * CODES command instead). Adds the ability to set the command abort timeout
 * and the ability to report the residual count. If timeout_secs is zero
 * or less the default command abort timeout (60 seconds) is used.
 * If residp is non-NULL then the residual value is written where residp
 * points. A residual value of 0 implies mx_resp_len bytes have be written
 * where resp points. If the residual value equals mx_resp_len then no
 * bytes have been written. */
int
sg_ll_inquiry_v2(int sg_fd, bool evpd, int pg_op, void * resp,
                 int mx_resp_len, int timeout_secs, int * residp,
                 bool noisy, int verbose)
{
    return sg_ll_inquiry_com(sg_fd, false, evpd, pg_op, resp, mx_resp_len,
                             timeout_secs, residp, noisy, verbose);
}

/* Invokes a SCSI TEST UNIT READY command.
 * 'pack_id' is just for diagnostics, safe to set to 0.
 * Looks for progress indicator if 'progress' non-NULL;
 * if found writes value [0..65535] else write -1.
 * Returns 0 when successful, various SG_LIB_CAT_* positive values or
 * -1 -> other errors */
int
sg_ll_test_unit_ready_progress(int sg_fd, int pack_id, int * progress,
                               bool noisy, int verbose)
{
    static const char * const tur_s = "test unit ready";
    int res, ret, k, sense_cat;
    unsigned char tur_cdb[TUR_CMDLEN] = {TUR_CMD, 0, 0, 0, 0, 0};
    unsigned char sense_b[SENSE_BUFF_LEN];
    struct sg_pt_base * ptvp;

    if (verbose) {
        pr2ws("    %s cdb: ", tur_s);
        for (k = 0; k < TUR_CMDLEN; ++k)
            pr2ws("%02x ", tur_cdb[k]);
        pr2ws("\n");
    }

    if (NULL == ((ptvp = create_pt_obj(tur_s))))
        return -1;
    set_scsi_pt_cdb(ptvp, tur_cdb, sizeof(tur_cdb));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    set_scsi_pt_packet_id(ptvp, pack_id);
    res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
    ret = sg_cmds_process_resp(ptvp, tur_s, res, SG_NO_DATA_IN, sense_b,
                               noisy, verbose, &sense_cat);
    if (-1 == ret) {
        int os_err = get_scsi_pt_os_err(ptvp);

        if ((os_err > 0) && (os_err < 47))
            ret = SG_LIB_OS_BASE_ERR + os_err;
    } else if (-2 == ret) {
        if (progress) {
            int slen = get_scsi_pt_sense_len(ptvp);

            if (! sg_get_sense_progress_fld(sense_b, slen, progress))
                *progress = -1;
        }
        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;

    destruct_scsi_pt_obj(ptvp);
    return ret;
}

/* Invokes a SCSI TEST UNIT READY command.
 * 'pack_id' is just for diagnostics, safe to set to 0.
 * Returns 0 when successful, various SG_LIB_CAT_* positive values or
 * -1 -> other errors */
int
sg_ll_test_unit_ready(int sg_fd, int pack_id, bool noisy, int verbose)
{
    return sg_ll_test_unit_ready_progress(sg_fd, pack_id, NULL, noisy,
                                          verbose);
}

/* Invokes a SCSI REQUEST SENSE command. Returns 0 when successful, various
 * SG_LIB_CAT_* positive values or -1 -> other errors */
int
sg_ll_request_sense(int sg_fd, bool desc, void * resp, int mx_resp_len,
                    bool noisy, int verbose)
{
    static const char * const rq_s = "request sense";
    int k, ret, res, sense_cat;
    unsigned char rs_cdb[REQUEST_SENSE_CMDLEN] =
        {REQUEST_SENSE_CMD, 0, 0, 0, 0, 0};
    unsigned char sense_b[SENSE_BUFF_LEN];
    struct sg_pt_base * ptvp;

    if (desc)
        rs_cdb[1] |= 0x1;
    if (mx_resp_len > 0xff) {
        pr2ws("mx_resp_len cannot exceed 255\n");
        return -1;
    }
    rs_cdb[4] = mx_resp_len & 0xff;
    if (verbose) {
        pr2ws("    %s cmd: ", rq_s);
        for (k = 0; k < REQUEST_SENSE_CMDLEN; ++k)
            pr2ws("%02x ", rs_cdb[k]);
        pr2ws("\n");
    }

    if (NULL == ((ptvp = create_pt_obj(rq_s))))
        return -1;
    set_scsi_pt_cdb(ptvp, rs_cdb, sizeof(rs_cdb));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len);
    res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
    ret = sg_cmds_process_resp(ptvp, rq_s, res, mx_resp_len, sense_b, noisy,
                               verbose, &sense_cat);
    if (-1 == ret) {
        int os_err = get_scsi_pt_os_err(ptvp);

        if ((os_err > 0) && (os_err < 47))
            ret = SG_LIB_OS_BASE_ERR + os_err;
    } 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 {
        if ((mx_resp_len >= 8) && (ret < 8)) {
            if (verbose)
                pr2ws("    %s: got %d bytes in response, too short\n", rq_s,
                      ret);
            ret = -1;
        } else
            ret = 0;
    }
    destruct_scsi_pt_obj(ptvp);
    return ret;
}

/* Invokes a SCSI REPORT LUNS command. Return of 0 -> success,
 * various SG_LIB_CAT_* positive values or -1 -> other errors */
int
sg_ll_report_luns(int sg_fd, int select_report, void * resp, int mx_resp_len,
                  bool noisy, int verbose)
{
    static const char * const report_luns_s = "report luns";
    int k, ret, res, sense_cat;
    unsigned char rl_cdb[REPORT_LUNS_CMDLEN] =
                         {REPORT_LUNS_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    unsigned char sense_b[SENSE_BUFF_LEN];
    struct sg_pt_base * ptvp;

    rl_cdb[2] = select_report & 0xff;
    sg_put_unaligned_be32((uint32_t)mx_resp_len, rl_cdb + 6);
    if (verbose) {
        pr2ws("    %s cdb: ", report_luns_s);
        for (k = 0; k < REPORT_LUNS_CMDLEN; ++k)
            pr2ws("%02x ", rl_cdb[k]);
        pr2ws("\n");
    }

    if (NULL == ((ptvp = create_pt_obj(report_luns_s))))
        return -1;
    set_scsi_pt_cdb(ptvp, rl_cdb, sizeof(rl_cdb));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len);
    res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
    ret = sg_cmds_process_resp(ptvp, report_luns_s, res, mx_resp_len,
                               sense_b, noisy, verbose, &sense_cat);
    if (-1 == ret) {
        int os_err = get_scsi_pt_os_err(ptvp);

        if ((os_err > 0) && (os_err < 47))
            ret = SG_LIB_OS_BASE_ERR + os_err;
    } 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;
    destruct_scsi_pt_obj(ptvp);
    return ret;
}
