diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2018-01-28 06:50:39 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2018-01-28 06:50:39 +0000 |
commit | 3a7e1666843ba386946f65d8ea89fe4ddf9ed9bf (patch) | |
tree | ec2d3a035ff39e5f5786460ac09f31df45d5469f /lib | |
parent | 6293187a432dd0bbf85961a897755bd0260f28ad (diff) | |
download | sg3_utils-3a7e1666843ba386946f65d8ea89fe4ddf9ed9bf.tar.gz |
add sg_seek and sg_stream_ctl utilities; properly identify vendor-specific sense; documentation cleanup
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@747 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.in | 1 | ||||
-rw-r--r-- | lib/sg_cmds_basic.c | 64 | ||||
-rw-r--r-- | lib/sg_cmds_basic2.c | 105 | ||||
-rw-r--r-- | lib/sg_cmds_extra.c | 399 | ||||
-rw-r--r-- | lib/sg_cmds_mmc.c | 36 | ||||
-rw-r--r-- | lib/sg_lib.c | 118 | ||||
-rw-r--r-- | lib/sg_lib_data.c | 2 | ||||
-rw-r--r-- | lib/sg_pt_freebsd.c | 1 | ||||
-rw-r--r-- | lib/sg_pt_linux.c | 5 |
9 files changed, 511 insertions, 220 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in index 13f243e0..4d772e2a 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -285,6 +285,7 @@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PTHREAD_LIB = @PTHREAD_LIB@ RANLIB = @RANLIB@ +RT_LIB = @RT_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c index cf5dfbc2..7405372e 100644 --- a/lib/sg_cmds_basic.c +++ b/lib/sg_cmds_basic.c @@ -36,7 +36,7 @@ #endif -static const char * const version_str = "1.80 20180117"; +static const char * const version_str = "1.82 20180126"; #define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ @@ -351,7 +351,7 @@ sg_ll_inquiry(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp, if (evpd) inq_cdb[1] |= 1; inq_cdb[2] = (unsigned char)pg_op; - /* 16 bit allocation length (was 8, increased in spc3r09, September 2002) */ + /* 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); @@ -374,10 +374,12 @@ sg_ll_inquiry(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp, ret = sg_cmds_process_resp(ptvp, inquiry_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); resid = get_scsi_pt_resid(ptvp); - destruct_scsi_pt_obj(ptvp); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -393,6 +395,7 @@ sg_ll_inquiry(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp, ret = SG_LIB_CAT_MALFORMED; } else ret = 0; + destruct_scsi_pt_obj(ptvp); if (resid > 0) { if (resid > mx_resp_len) { @@ -441,9 +444,12 @@ sg_simple_inquiry(int sg_fd, struct sg_simple_inquiry_resp * inq_data, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, inquiry_s, res, sizeof(inq_resp), sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -502,7 +508,7 @@ sg_ll_inquiry_v2(int sg_fd, bool evpd, int pg_op, void * resp, if (evpd) inq_cdb[1] |= 1; inq_cdb[2] = (unsigned char)pg_op; - /* 16 bit allocation length (was 8, increased in spc3r09, September 2002) */ + /* 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(" inquiry cdb: "); @@ -534,10 +540,12 @@ sg_ll_inquiry_v2(int sg_fd, bool evpd, int pg_op, void * resp, resid = get_scsi_pt_resid(ptvp); if (residp) *residp = resid; - destruct_scsi_pt_obj(ptvp); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -553,6 +561,7 @@ sg_ll_inquiry_v2(int sg_fd, bool evpd, int pg_op, void * resp, ret = SG_LIB_CAT_MALFORMED; } else ret = 0; + destruct_scsi_pt_obj(ptvp); if (resid > 0) { if (resid > mx_resp_len) { @@ -597,9 +606,12 @@ sg_ll_test_unit_ready_progress(int sg_fd, int pack_id, int * progress, 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) - ; - else if (-2 == ret) { + 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); @@ -668,9 +680,12 @@ sg_ll_request_sense(int sg_fd, bool desc, void * resp, int 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) - ; - else if (-2 == ret) { + 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: @@ -723,9 +738,12 @@ sg_ll_report_luns(int sg_fd, int select_report, void * resp, int 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) - ; - else if (-2 == ret) { + 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: diff --git a/lib/sg_cmds_basic2.c b/lib/sg_cmds_basic2.c index 9a0f283c..18b6cd7e 100644 --- a/lib/sg_cmds_basic2.c +++ b/lib/sg_cmds_basic2.c @@ -137,9 +137,12 @@ sg_ll_sync_cache_10(int sg_fd, bool sync_nv, bool immed, int group, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -190,9 +193,12 @@ sg_ll_readcap_16(int sg_fd, bool pmi, uint64_t llba, void * resp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -240,9 +246,12 @@ sg_ll_readcap_10(int sg_fd, bool pmi, unsigned int lba, void * resp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -295,10 +304,12 @@ sg_ll_mode_sense6(int sg_fd, bool dbd, int pc, int pg_code, int sub_pg_code, ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); resid = get_scsi_pt_resid(ptvp); - destruct_scsi_pt_obj(ptvp); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -322,6 +333,7 @@ sg_ll_mode_sense6(int sg_fd, bool dbd, int pc, int pg_code, int sub_pg_code, } ret = 0; } + destruct_scsi_pt_obj(ptvp); if (resid > 0) { if (resid > mx_resp_len) { @@ -395,10 +407,12 @@ sg_ll_mode_sense10_v2(int sg_fd, bool llbaa, bool dbd, int pc, int pg_code, resid = get_scsi_pt_resid(ptvp); if (residp) *residp = resid; - destruct_scsi_pt_obj(ptvp); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -422,6 +436,7 @@ sg_ll_mode_sense10_v2(int sg_fd, bool llbaa, bool dbd, int pc, int pg_code, } ret = 0; } + destruct_scsi_pt_obj(ptvp); if (resid > 0) { if (resid > mx_resp_len) { @@ -477,9 +492,12 @@ sg_ll_mode_select6(int sg_fd, bool pf, bool sp, void * paramp, int param_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -534,9 +552,12 @@ sg_ll_mode_select10(int sg_fd, bool pf, bool sp, void * paramp, int param_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -824,10 +845,12 @@ sg_ll_log_sense_v2(int sg_fd, bool ppc, bool sp, int pc, int pg_code, resid = get_scsi_pt_resid(ptvp); if (residp) *residp = resid; - destruct_scsi_pt_obj(ptvp); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -845,6 +868,7 @@ sg_ll_log_sense_v2(int sg_fd, bool ppc, bool sp, int pc, int pg_code, } ret = 0; } + destruct_scsi_pt_obj(ptvp); if (resid > 0) { if (resid > mx_resp_len) { @@ -903,9 +927,12 @@ sg_ll_log_select(int sg_fd, bool pcr, bool sp, int pc, int pg_code, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -965,9 +992,12 @@ sg_ll_start_stop_unit(int sg_fd, bool immed, int pc_mod__fl_num, res = do_scsi_pt(ptvp, sg_fd, START_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1017,9 +1047,12 @@ sg_ll_prevent_allow(int sg_fd, int prevent, bool noisy, int verbose) res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c index d94c5bc4..bebc8592 100644 --- a/lib/sg_cmds_extra.c +++ b/lib/sg_cmds_extra.c @@ -81,6 +81,12 @@ #define WRITE_LONG10_CMDLEN 10 #define WRITE_BUFFER_CMD 0x3b #define WRITE_BUFFER_CMDLEN 10 +#define PRE_FETCH10_CMD 0x34 +#define PRE_FETCH10_CMDLEN 10 +#define PRE_FETCH16_CMD 0x90 +#define PRE_FETCH16_CMDLEN 16 +#define SEEK10_CMD 0x2b +#define SEEK10_CMDLEN 10 #define GET_LBA_STATUS16_SA 0x12 #define GET_LBA_STATUS32_SA 0x12 @@ -158,9 +164,12 @@ sg_ll_get_lba_status16(int sg_fd, uint64_t start_llba, uint8_t rt, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, alloc_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -234,9 +243,12 @@ sg_ll_get_lba_status32(int sg_fd, uint64_t start_llba, uint32_t scan_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, alloc_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -278,7 +290,7 @@ int sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len, bool extended, bool noisy, int verbose) { - static const char * const cdb_name_s = "report target port groups"; + static const char * const cdb_name_s = "Report target port groups"; int k, res, ret, sense_cat; unsigned char rtpg_cdb[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD, REPORT_TGT_PRT_GRP_SA, @@ -304,9 +316,12 @@ sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -340,7 +355,7 @@ int sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "set target port groups"; + static const char * const cdb_name_s = "Set target port groups"; int k, res, ret, sense_cat; unsigned char stpg_cdb[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD, SET_TGT_PRT_GRP_SA, @@ -368,9 +383,12 @@ sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, bool noisy, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -393,7 +411,7 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg, void * resp, int mx_resp_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "report referrals"; + static const char * const cdb_name_s = "Report referrals"; int k, res, ret, sense_cat; unsigned char repRef_cdb[SERVICE_ACTION_IN_16_CMDLEN] = {SERVICE_ACTION_IN_16_CMD, REPORT_REFERRALS_SA, @@ -420,9 +438,12 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -460,7 +481,7 @@ sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit, bool devofl_bit, bool unitofl_bit, int long_duration, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "send diagnostic"; + static const char * const cdb_name_s = "Send diagnostic"; int k, res, ret, sense_cat, tmout; unsigned char senddiag_cdb[SEND_DIAGNOSTIC_CMDLEN] = {SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0}; @@ -504,9 +525,12 @@ sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit, res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -542,7 +566,7 @@ sg_ll_receive_diag_v2(int sg_fd, bool pcv, int pg_code, void * resp, { int resid = 0; int k, res, ret, sense_cat; - static const char * const cdb_name_s = "receive diagnostic results"; + static const char * const cdb_name_s = "Receive diagnostic results"; struct sg_pt_base * ptvp; unsigned char rcvdiag_cdb[RECEIVE_DIAGNOSTICS_CMDLEN] = {RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0}; @@ -576,9 +600,12 @@ sg_ll_receive_diag_v2(int sg_fd, bool pcv, int pg_code, void * resp, resid = get_scsi_pt_resid(ptvp); if (residp) *residp = resid; - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -612,7 +639,7 @@ int sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format, void * resp, int mx_resp_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "read defect(10)"; + static const char * const cdb_name_s = "Read defect(10)"; int res, k, ret, sense_cat; unsigned char rdef_cdb[READ_DEFECT10_CMDLEN] = {READ_DEFECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -644,9 +671,12 @@ sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -680,7 +710,7 @@ int sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "read media serial number"; + static const char * const cdb_name_s = "Read media serial number"; int k, res, ret, sense_cat; unsigned char rmsn_cdb[SERVICE_ACTION_IN_12_CMDLEN] = {SERVICE_ACTION_IN_12_CMD, READ_MEDIA_SERIAL_NUM_SA, @@ -704,9 +734,12 @@ sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -741,7 +774,7 @@ int sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "report identifying information"; + static const char * const cdb_name_s = "Report identifying information"; int k, res, ret, sense_cat; unsigned char rii_cdb[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD, REPORT_IDENTIFYING_INFORMATION_SA, @@ -767,9 +800,12 @@ sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, max_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -804,7 +840,7 @@ int sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "set identifying information"; + static const char * const cdb_name_s = "Set identifying information"; int k, res, ret, sense_cat; unsigned char sii_cdb[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD, SET_IDENTIFYING_INFORMATION_SA, @@ -833,9 +869,12 @@ sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -885,7 +924,7 @@ sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata, int timeout_secs, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "format unit"; + static const char * const cdb_name_s = "Format unit"; int k, res, ret, sense_cat, tmout; unsigned char fu_cdb[FORMAT_UNIT_CMDLEN] = {FORMAT_UNIT_CMD, 0, 0, 0, 0, 0}; @@ -927,9 +966,12 @@ sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata, res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -952,7 +994,7 @@ int sg_ll_reassign_blocks(int sg_fd, bool longlba, bool longlist, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "reassign blocks"; + static const char * const cdb_name_s = "Reassign blocks"; int res, k, ret, sense_cat; unsigned char reass_cdb[REASSIGN_BLKS_CMDLEN] = {REASSIGN_BLKS_CMD, 0, 0, 0, 0, 0}; @@ -982,9 +1024,12 @@ sg_ll_reassign_blocks(int sg_fd, bool longlba, bool longlist, void * paramp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1008,7 +1053,7 @@ int sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp, int mx_resp_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "persistent reservation in"; + static const char * const cdb_name_s = "Persistent reservation in"; int res, k, ret, sense_cat; unsigned char prin_cdb[PERSISTENT_RESERVE_IN_CMDLEN] = {PERSISTENT_RESERVE_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -1034,9 +1079,12 @@ sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1072,7 +1120,7 @@ sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope, unsigned int rq_type, void * paramp, int param_len, bool noisy, int verbose) { - static const char * const cdb_name_s = "persistent reservation out"; + static const char * const cdb_name_s = "Persistent reservation out"; int res, k, ret, sense_cat; unsigned char prout_cdb[PERSISTENT_RESERVE_OUT_CMDLEN] = {PERSISTENT_RESERVE_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -1103,9 +1151,12 @@ sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1178,9 +1229,12 @@ sg_ll_read_long10(int sg_fd, bool pblock, bool correct, unsigned int lba, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, xfer_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1268,9 +1322,12 @@ sg_ll_read_long16(int sg_fd, bool pblock, bool correct, uint64_t llba, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, xfer_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1439,9 +1496,12 @@ sg_ll_write_long16(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1481,8 +1541,8 @@ sg_ll_write_long16(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock, /* Invokes a SCSI VERIFY (10) command (SBC and MMC). * Note that 'veri_len' is in blocks while 'data_out_len' is in bytes. - * Returns of 0 -> success, - * various SG_LIB_CAT_* positive values or -1 -> other errors */ + * Returns of 0 -> success, * various SG_LIB_CAT_* positive values or + * -1 -> other errors */ int sg_ll_verify10(int sg_fd, int vrprotect, bool dpo, int bytchk, unsigned int lba, int veri_len, void * data_out, @@ -1523,9 +1583,12 @@ sg_ll_verify10(int sg_fd, int vrprotect, bool dpo, int bytchk, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1601,9 +1664,12 @@ sg_ll_verify16(int sg_fd, int vrprotect, bool dpo, int bytchk, uint64_t llba, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1841,9 +1907,12 @@ sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1914,9 +1983,12 @@ sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -1991,9 +2063,12 @@ sg_ll_write_buffer_v2(int sg_fd, int mode, int m_specific, int buffer_id, res = do_scsi_pt(ptvp, sg_fd, timeout_secs, verbose); ret = sg_cmds_process_resp(ptvp, "Write buffer", res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -2057,9 +2132,12 @@ sg_ll_unmap_v2(int sg_fd, bool anchor, int group_num, int timeout_secs, res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -2103,9 +2181,12 @@ sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -2170,9 +2251,12 @@ sg_ll_receive_copy_results(int sg_fd, int sa, int list_id, void * resp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, b, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -2229,9 +2313,12 @@ sg_ll_extended_copy(int sg_fd, void * paramp, int param_len, bool noisy, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, opcode_name, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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: @@ -2282,7 +2369,7 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num, sg_put_unaligned_be32((uint32_t)list_id, xcopy_cdb + 2); break; default: - pr2ws("sg_ll_3party_copy_out: unknown service action 0x%x\n", sa); + pr2ws("%s: unknown service action 0x%x\n", __func__, sa); return -1; } tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT; @@ -2306,9 +2393,120 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num, res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, cname, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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; +} + +/* Invokes a SCSI PRE-FETCH(10), PRE-FETCH(16) or SEEK(10) command (SBC). + * Returns 0 -> success, 25 (SG_LIB_CAT_CONDITION_MET), various SG_LIB_CAT_* + * positive values or -1 -> other errors. Note that CONDITION MET status + * is returned when immed=true and num_blocks can fit in device's cache, + * somewaht strangely, GOOD status (return 0) is returned if num_blocks + * cannot fit in device's cache. If do_seek10==true then does a SEEK(10) + * command with given lba, if that LBA is < 2**32 . Unclear what SEEK(10) + * does, assume it is like PRE-FETCH. If timeout_secs is 0 (or less) then + * use DEF_PT_TIMEOUT (60 seconds) as command timeout. */ +int +sg_ll_pre_fetch_x(int sg_fd, bool do_seek10, bool cdb16, bool immed, + uint64_t lba, uint32_t num_blocks, int group_num, + int timeout_secs, bool noisy, int verbose) +{ + static const char * const cdb10_name_s = "Pre-fetch(10)"; + static const char * const cdb16_name_s = "Pre-fetch(16)"; + static const char * const cdb_seek_name_s = "Seek(10)"; + int k, res, sense_cat, ret, cdb_len, tmout; + const char *cdb_name_s; + unsigned char preFetchCdb[PRE_FETCH16_CMDLEN]; /* all use longest cdb */ + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_pt_base * ptvp; + + memset(preFetchCdb, 0, sizeof(preFetchCdb)); + if (do_seek10) { + if (lba > UINT32_MAX) { + if (verbose) + pr2ws("%s: LBA exceeds 2**32 in %s\n", __func__, + cdb_seek_name_s); + return -1; + } + preFetchCdb[0] = SEEK10_CMD; + cdb_len = SEEK10_CMDLEN; + cdb_name_s = cdb_seek_name_s; + sg_put_unaligned_be32((uint32_t)lba, preFetchCdb + 2); + } else { + if ((! cdb16) && + ((lba > UINT32_MAX) || (num_blocks > UINT16_MAX))) { + cdb16 = true; + if (noisy || verbose) + pr2ws("%s: do %s due to %s size\n", __func__, cdb16_name_s, + (lba > UINT32_MAX) ? "LBA" : "NUM_BLOCKS"); + } + if (cdb16) { + preFetchCdb[0] = PRE_FETCH16_CMD; + cdb_len = PRE_FETCH16_CMDLEN; + cdb_name_s = cdb16_name_s; + if (immed) + preFetchCdb[1] = 0x2; + sg_put_unaligned_be64(lba, preFetchCdb + 2); + sg_put_unaligned_be32(num_blocks, preFetchCdb + 10); + preFetchCdb[14] = 0x3f & group_num; + } else { + preFetchCdb[0] = PRE_FETCH10_CMD; + cdb_len = PRE_FETCH10_CMDLEN; + cdb_name_s = cdb10_name_s; + if (immed) + preFetchCdb[1] = 0x2; + sg_put_unaligned_be32((uint32_t)lba, preFetchCdb + 2); + preFetchCdb[6] = 0x3f & group_num; + sg_put_unaligned_be16((uint16_t)num_blocks, preFetchCdb + 7); + } + } + tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT; + if (verbose) { + pr2ws(" %s cdb: ", cdb_name_s); + for (k = 0; k < cdb_len; ++k) + pr2ws("%02x ", preFetchCdb[k]); + pr2ws("\n"); + } + if (NULL == ((ptvp = create_pt_obj(cdb_name_s)))) + return -1; + set_scsi_pt_cdb(ptvp, preFetchCdb, cdb_len); + set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); + res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); + if (0 == res) { + int sstat = get_scsi_pt_status_response(ptvp); + + if (SG_LIB_CAT_CONDITION_MET == sstat) { + ret = SG_LIB_CAT_CONDITION_MET; + if (verbose > 2) + pr2ws("%s: returns SG_LIB_CAT_CONDITION_MET\n", __func__); + goto fini; + } + } + ret = sg_cmds_process_resp(ptvp, cdb_name_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) { switch (sense_cat) { case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: @@ -2320,6 +2518,7 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num, } } else ret = 0; +fini: destruct_scsi_pt_obj(ptvp); return ret; } diff --git a/lib/sg_cmds_mmc.c b/lib/sg_cmds_mmc.c index 0e003b82..18f6ae1a 100644 --- a/lib/sg_cmds_mmc.c +++ b/lib/sg_cmds_mmc.c @@ -99,9 +99,12 @@ sg_ll_set_cd_speed(int sg_fd, int rot_control, int drv_read_speed, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: @@ -171,9 +174,12 @@ sg_ll_get_config(int sg_fd, int rt, int starting, void * resp, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: @@ -263,9 +269,12 @@ sg_ll_get_performance(int sg_fd, int data_type, unsigned int starting_lba, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: @@ -344,9 +353,12 @@ sg_ll_set_streaming(int sg_fd, int type, void * paramp, int param_len, res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cdb_name_s, res, SG_NO_DATA_IN, sense_b, noisy, verbose, &sense_cat); - if (-1 == ret) - ; - else if (-2 == ret) { + 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_NOT_READY: case SG_LIB_CAT_INVALID_OP: diff --git a/lib/sg_lib.c b/lib/sg_lib.c index e2685499..61653260 100644 --- a/lib/sg_lib.c +++ b/lib/sg_lib.c @@ -1606,22 +1606,23 @@ sg_get_sense_sat_pt_fixed_str(const char * lip, const unsigned char * sp, /* Fetch sense information */ int sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len, - bool raw_sinfo, int buff_len, char * buff) + bool raw_sinfo, int cblen, char * cbp) { - int len, progress, n, r, pr, rem, blen; - unsigned int info; bool descriptor_format = false; bool sdat_ovfl = false; bool valid; + int len, progress, n, r, pr, rem, blen; + unsigned int info; + uint8_t resp_code; const char * ebp = NULL; - char error_buff[64]; + char ebuff[64]; char b[256]; struct sg_scsi_sense_hdr ssh; - if ((NULL == buff) || (buff_len <= 0)) + if ((NULL == cbp) || (cblen <= 0)) return 0; - else if (1 == buff_len) { - buff[0] = '\0'; + else if (1 == cblen) { + cbp[0] = '\0'; return 0; } blen = sizeof(b); @@ -1629,9 +1630,11 @@ sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len, if (NULL == lip) lip = ""; if ((NULL == sbp) || (sb_len < 1)) { - n += scnpr(buff, buff_len, "%s >>> sense buffer empty\n", lip); + n += scnpr(cbp, cblen, "%s >>> sense buffer empty\n", lip); return n; } + resp_code = 0x7f & sbp[0]; + valid = !!(sbp[0] & 0x80); len = sb_len; if (sg_scsi_normalize_sense(sbp, sb_len, &ssh)) { switch (ssh.response_code) { @@ -1662,36 +1665,33 @@ sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len, ebp = "Response code: 0x0 (?)"; break; default: - scnpr(error_buff, sizeof(error_buff), "Unknown response code: " - "0x%x", ssh.response_code); - ebp = error_buff; + scnpr(ebuff, sizeof(ebuff), "Unknown response code: 0x%x", + ssh.response_code); + ebp = ebuff; break; } - n += scnpr(buff + n, buff_len - n, "%s%s; Sense key: %s\n", lip, ebp, + n += scnpr(cbp + n, cblen - n, "%s%s; Sense key: %s\n", lip, ebp, sg_lib_sense_key_desc[ssh.sense_key]); if (sdat_ovfl) - n += scnpr(buff + n, buff_len - n, "%s<<<Sense data " - "overflow>>>\n", lip); + n += scnpr(cbp + n, cblen - n, "%s<<<Sense data overflow>>>\n", + lip); if (descriptor_format) { - n += scnpr(buff + n, buff_len - n, "%s%s\n", lip, - sg_get_asc_ascq_str(ssh.asc, ssh.ascq, sizeof(b), b)); + n += scnpr(cbp + n, cblen - n, "%s%s\n", lip, + sg_get_asc_ascq_str(ssh.asc, ssh.ascq, blen, b)); n += sg_get_sense_descriptors_str(lip, sbp, len, - buff_len - n, buff + n); + cblen - n, cbp + n); } else if ((len > 12) && (0 == ssh.asc) && (ASCQ_ATA_PT_INFO_AVAILABLE == ssh.ascq)) { /* SAT ATA PASS-THROUGH fixed format */ - n += scnpr(buff + n, buff_len - n, "%s%s\n", lip, - sg_get_asc_ascq_str(ssh.asc, ssh.ascq, - sizeof(b), b)); + n += scnpr(cbp + n, cblen - n, "%s%s\n", lip, + sg_get_asc_ascq_str(ssh.asc, ssh.ascq, blen, b)); n += sg_get_sense_sat_pt_fixed_str(lip, sbp, len, - buff_len - n, buff + n); + cblen - n, cbp + n); } else if (len > 2) { /* fixed format */ if (len > 12) - n += scnpr(buff + n, buff_len - n, "%s%s\n", lip, - sg_get_asc_ascq_str(ssh.asc, ssh.ascq, - sizeof(b), b)); + n += scnpr(cbp + n, cblen - n, "%s%s\n", lip, + sg_get_asc_ascq_str(ssh.asc, ssh.ascq, blen, b)); r = 0; - valid = !!(sbp[0] & 0x80); if (strlen(lip) > 0) r += scnpr(b + r, blen - r, "%s", lip); if (len > 6) { @@ -1774,41 +1774,49 @@ sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len, } } if (r > 0) - n += scnpr(buff + n, buff_len - n, "%s", b); + n += scnpr(cbp + n, cblen - n, "%s", b); } else - n += scnpr(buff + n, buff_len - n, "%s fixed descriptor length " + n += scnpr(cbp + n, cblen - n, "%s fixed descriptor length " "too short, len=%d\n", lip, len); - } else { /* non-extended SCSI-1 sense data ?? */ - if (sb_len < 4) { - n += scnpr(buff + n, buff_len - n, "%ssense buffer too short (4 " + } else { /* unable to normalise sense buffer, something irregular */ + if (sb_len < 4) { /* Too short */ + n += scnpr(cbp + n, cblen - n, "%ssense buffer too short (4 " "byte minimum)\n", lip); - return n; + goto check_raw; + } + if (0x7f == resp_code) { /* Vendor specific */ + n += scnpr(cbp + n, cblen - n, "%sVendor specific sense buffer, " + "in hex:\n", lip); + n += hex2str(sbp, sb_len, lip, -1, cblen - n, cbp + n); + return n; /* no need to check raw, just output in hex */ } + /* non-extended SCSI-1 sense data ?? */ r = 0; if (strlen(lip) > 0) r += scnpr(b + r, blen - r, "%s", lip); r += scnpr(b + r, blen - r, "Probably uninitialized data.\n%s Try " "to view as SCSI-1 non-extended sense:\n", lip); r += scnpr(b + r, blen - r, " AdValid=%d Error class=%d Error " - "code=%d\n", !!(sbp[0] & 0x80), ((sbp[0] >> 4) & 0x7), + "code=%d\n", valid, ((sbp[0] >> 4) & 0x7), (sbp[0] & 0xf)); - if (sbp[0] & 0x80) + if (valid) scnpr(b + r, blen - r, "%s lba=0x%x\n", lip, sg_get_unaligned_be24(sbp + 1) & 0x1fffff); - n += scnpr(buff + n, buff_len - n, "%s\n", b); + n += scnpr(cbp + n, cblen - n, "%s\n", b); len = sb_len; if (len > 32) len = 32; /* trim in case there is a lot of rubbish */ } +check_raw: if (raw_sinfo) { char z[64]; - n += scnpr(buff + n, buff_len - n, "%s Raw sense data (in hex):\n", + n += scnpr(cbp + n, cblen - n, "%s Raw sense data (in hex):\n", lip); - if (n >= (buff_len - 1)) + if (n >= (cblen - 1)) return n; scnpr(z, sizeof(z), "%.50s ", lip); - n += hex2str(sbp, len, z, 1, buff_len - n, buff + n); + n += hex2str(sbp, len, z, -1, cblen - n, cbp + n); } return n; } @@ -1818,10 +1826,16 @@ void sg_print_sense(const char * leadin, const unsigned char * sbp, int sb_len, bool raw_sinfo) { - char b[2048]; + uint32_t pg_sz = sg_get_page_size(); + char *cp; + uint8_t *free_cp; - sg_get_sense_str(leadin, sbp, sb_len, raw_sinfo, sizeof(b), b); - pr2ws("%s", b); + cp = (char *)sg_memalign(pg_sz, pg_sz, &free_cp, 0); + if (NULL == cp) + return; + sg_get_sense_str(leadin, sbp, sb_len, raw_sinfo, pg_sz, cp); + pr2ws("%s", cp); + free(free_cp); } /* See description in sg_lib.h header file */ @@ -1829,12 +1843,16 @@ bool sg_scsi_normalize_sense(const unsigned char * sbp, int sb_len, struct sg_scsi_sense_hdr * sshp) { + uint8_t resp_code; if (sshp) memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr)); - if ((NULL == sbp) || (0 == sb_len) || (0x70 != (0x70 & sbp[0]))) + if ((NULL == sbp) || (sb_len < 1)) + return false; + resp_code = 0x7f & sbp[0]; + if ((resp_code < 0x70) || (resp_code > 0x73)) return false; if (sshp) { - sshp->response_code = (0x7f & sbp[0]); + sshp->response_code = resp_code; if (sshp->response_code >= 0x72) { /* descriptor format */ if (sb_len > 1) sshp->sense_key = (0xf & sbp[1]); @@ -2258,10 +2276,18 @@ sg_get_category_sense_str(int sense_cat, int buff_len, char * buff, "issue"); break; default: - n = scnpr(buff, buff_len, "Sense category: %d", sense_cat); - if ((0 == verbose) && (n < (buff_len - 1))) - scnpr(buff + n, buff_len - n, ", try '-v' option for more " - "information"); + if ((sense_cat > SG_LIB_OS_BASE_ERR) && + (sense_cat < (SG_LIB_OS_BASE_ERR + 47))) { + int k = sense_cat - SG_LIB_OS_BASE_ERR; + + n = scnpr(buff, buff_len, "OS error: %s [%d]", safe_strerror(k), + k); + } else { + n = scnpr(buff, buff_len, "Sense category: %d", sense_cat); + if ((0 == verbose) && (n < (buff_len - 1))) + scnpr(buff + n, buff_len - n, ", try '-v' option for more " + "information"); + } break; } return buff; diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c index 9e34e075..211054d2 100644 --- a/lib/sg_lib_data.c +++ b/lib/sg_lib_data.c @@ -17,7 +17,7 @@ #include "sg_lib_data.h" -const char * sg_lib_version_str = "2.38 20180118";/* spc5r17, sbc4r15 */ +const char * sg_lib_version_str = "2.38 20180122";/* spc5r17, sbc4r15 */ /* indexed by pdt; those that map to own index do not decay */ diff --git a/lib/sg_pt_freebsd.c b/lib/sg_pt_freebsd.c index b764738c..ba41c8bf 100644 --- a/lib/sg_pt_freebsd.c +++ b/lib/sg_pt_freebsd.c @@ -612,6 +612,7 @@ do_scsi_pt(struct sg_pt_base * vp, int dev_han, int time_secs, int verbose) pr2ws("%s: No device file handle given\n", __func__); return SCSI_PT_DO_BAD_PARAMS; } + dev_han = ptp->dev_han; } else { if (ptp->dev_han >= 0) { if (dev_han != ptp->dev_han) { diff --git a/lib/sg_pt_linux.c b/lib/sg_pt_linux.c index 4b433054..71311a17 100644 --- a/lib/sg_pt_linux.c +++ b/lib/sg_pt_linux.c @@ -5,7 +5,7 @@ * license that can be found in the BSD_LICENSE file. */ -/* sg_pt_linux version 1.36 20180119 */ +/* sg_pt_linux version 1.37 20180126 */ #include <stdio.h> @@ -909,7 +909,8 @@ do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) if (verbose) pr2ws("%s: invalid file descriptors\n", __func__); return SCSI_PT_DO_BAD_PARAMS; - } + } else + fd = ptp->dev_fd; if (! have_checked_for_type) { err = set_pt_file_handle(vp, ptp->dev_fd, verbose); if (err) |