diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2018-05-02 22:02:05 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2018-05-02 22:02:05 +0000 |
commit | a59b767b38f08c0dafc011a58e8791aa06d4feb0 (patch) | |
tree | 8be0500cec5edb562779bc41f0ef7ad46b8c86fc /src | |
parent | f65566c3934a9e22335dee20401cc1cc50865d56 (diff) | |
download | sg3_utils-a59b767b38f08c0dafc011a58e8791aa06d4feb0.tar.gz |
sg_lib: add sg_ll_inquiry_pt(), sg_ll_test_unit_ready_progress_pt(), sg_ll_request_sense_pt(), sg_ll_send_diag_pt(), sg_ll_receive_diag_pt(); sg_timestamp: add --elapsed, --hex and --no-timestamp options; sg_ses: check for NVMe enclosure bits
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@769 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/Makefile.in | 5 | ||||
-rw-r--r-- | src/sg_compare_and_write.c | 26 | ||||
-rw-r--r-- | src/sg_copy_results.c | 13 | ||||
-rw-r--r-- | src/sg_dd.c | 4 | ||||
-rw-r--r-- | src/sg_get_lba_status.c | 34 | ||||
-rw-r--r-- | src/sg_inq.c | 3 | ||||
-rw-r--r-- | src/sg_logs.c | 46 | ||||
-rw-r--r-- | src/sg_luns.c | 12 | ||||
-rw-r--r-- | src/sg_modes.c | 2 | ||||
-rw-r--r-- | src/sg_opcodes.c | 45 | ||||
-rw-r--r-- | src/sg_raw.c | 6 | ||||
-rw-r--r-- | src/sg_read.c | 4 | ||||
-rw-r--r-- | src/sg_read_attr.c | 14 | ||||
-rw-r--r-- | src/sg_read_long.c | 5 | ||||
-rw-r--r-- | src/sg_referrals.c | 17 | ||||
-rw-r--r-- | src/sg_rep_zones.c | 15 | ||||
-rw-r--r-- | src/sg_sanitize.c | 2 | ||||
-rw-r--r-- | src/sg_ses.c | 244 | ||||
-rw-r--r-- | src/sg_stream_ctl.c | 18 | ||||
-rw-r--r-- | src/sg_test_rwbuf.c | 24 | ||||
-rw-r--r-- | src/sg_timestamp.c | 165 | ||||
-rw-r--r-- | src/sg_vpd.c | 3 | ||||
-rw-r--r-- | src/sg_write_long.c | 18 | ||||
-rw-r--r-- | src/sg_write_same.c | 15 | ||||
-rw-r--r-- | src/sg_write_verify.c | 17 | ||||
-rw-r--r-- | src/sg_write_x.c | 22 | ||||
-rw-r--r-- | src/sginfo.c | 2 | ||||
-rw-r--r-- | src/sgm_dd.c | 28 | ||||
-rw-r--r-- | src/sgp_dd.c | 104 |
30 files changed, 592 insertions, 324 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2407435f..18985656 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,7 @@ endif # For C++/clang testing -## CC = gcc +## CC = gcc-8 ## CC = g++ ## CC = clang ## CC = clang++ @@ -49,6 +49,7 @@ AM_CFLAGS = -Wall -W # AM_CFLAGS = -Wall -W -pedantic -std=c11 # AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze # AM_CFLAGS = -Wall -W -pedantic -std=c++14 +# AM_CFLAGS = -Wall -W -pedantic -std=c++1z sg_bg_ctl_LDADD = ../lib/libsgutils2.la diff --git a/src/Makefile.in b/src/Makefile.in index 999c0f4b..dc56ca9c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -579,6 +579,7 @@ AM_CFLAGS = -Wall -W # AM_CFLAGS = -Wall -W -pedantic -std=c11 # AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze # AM_CFLAGS = -Wall -W -pedantic -std=c++14 +# AM_CFLAGS = -Wall -W -pedantic -std=c++1z sg_bg_ctl_LDADD = ../lib/libsgutils2.la sg_compare_and_write_LDADD = ../lib/libsgutils2.la sg_copy_results_LDADD = ../lib/libsgutils2.la diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c index 1ede6e88..e4dbc5ae 100644 --- a/src/sg_compare_and_write.c +++ b/src/sg_compare_and_write.c @@ -54,7 +54,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.22 20180219"; +static const char * version_str = "1.22 20180428"; #define DEF_BLOCK_SIZE 512 #define DEF_NUM_BLOCKS (1) @@ -457,11 +457,12 @@ int main(int argc, char * argv[]) { bool ifn_stdin; - int res, half_xlen; + int res, half_xlen, vb; int infd = -1; int wfd = -1; int devfd = -1; uint8_t * wrkBuff = NULL; + uint8_t * free_wrkBuff = NULL; struct opts_t * op; struct opts_t opts; @@ -473,7 +474,8 @@ main(int argc, char * argv[]) goto out; } - if (op->verbose) { + vb = op->verbose; + if (vb) { pr2serr("Running COMPARE AND WRITE command with the " "following options:\n in=%s ", op->ifn); if (op->wfn_given) @@ -501,16 +503,17 @@ main(int argc, char * argv[]) } } - devfd = open_dev(op->device_name, op->verbose); + devfd = open_dev(op->device_name, vb); if (devfd < 0) { res = -devfd; goto out; } - wrkBuff = (uint8_t *)malloc(op->xfer_len); - if (0 == wrkBuff) { + wrkBuff = (uint8_t *)sg_memalign(op->xfer_len, 0, &free_wrkBuff, + vb > 3); + if (NULL == wrkBuff) { pr2serr("Not enough user memory\n"); - res = SG_LIB_CAT_OTHER; + res = sg_convert_errno(ENOMEM); goto out; } @@ -547,7 +550,7 @@ main(int argc, char * argv[]) } res = sg_ll_compare_and_write(devfd, wrkBuff, op->numblocks, op->lba, op->xfer_len, op->flags, ! op->quiet, - op->verbose); + vb); out: if (0 != res) { @@ -559,15 +562,14 @@ out: case SG_LIB_FILE_ERROR: break; /* already reported */ default: - sg_get_category_sense_str(res, sizeof(b), b, - op->verbose); + sg_get_category_sense_str(res, sizeof(b), b, vb); pr2serr(ME "SCSI COMPARE AND WRITE: %s\n", b); break; } } - if (wrkBuff) - free(wrkBuff); + if (free_wrkBuff) + free(free_wrkBuff); if ((infd >= 0) && (! ifn_stdin)) close(infd); if (wfd >= 0) diff --git a/src/sg_copy_results.c b/src/sg_copy_results.c index 97cd5388..514a33b9 100644 --- a/src/sg_copy_results.c +++ b/src/sg_copy_results.c @@ -38,7 +38,7 @@ and the optional list identifier passed as the list_id argument. */ -static const char * version_str = "1.19 20180326"; +static const char * version_str = "1.20 20180428"; #define MAX_XFER_LEN 10000 @@ -314,6 +314,7 @@ main(int argc, char * argv[]) uint32_t list_id = 0; const char * cp; uint8_t * cpResultBuff = NULL; + uint8_t * free_cprb = NULL; const char * device_name = NULL; char file_name[256]; @@ -401,11 +402,12 @@ main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } - if (NULL == (cpResultBuff = (uint8_t *)malloc(xfer_len))) { + cpResultBuff = (uint8_t *)sg_memalign(xfer_len, 0, &free_cprb, + verbose > 3); + if (NULL == cpResultBuff) { pr2serr(ME "out of memory\n"); - return SG_LIB_FILE_ERROR; + return sg_convert_errno(ENOMEM); } - memset(cpResultBuff, 0x00, xfer_len); sg_fd = sg_cmds_open_device(device_name, o_readonly, verbose); if (sg_fd < 0) { @@ -453,7 +455,8 @@ main(int argc, char * argv[]) } finish: - free(cpResultBuff); + if (free_cprb) + free(free_cprb); res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr(ME "close error: %s\n", safe_strerror(-res)); diff --git a/src/sg_dd.c b/src/sg_dd.c index 6abc50f4..af168fc6 100644 --- a/src/sg_dd.c +++ b/src/sg_dd.c @@ -62,7 +62,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "5.97 20180219"; +static const char * version_str = "5.98 20180502"; #define ME "sg_dd: " @@ -71,7 +71,7 @@ static const char * version_str = "5.97 20180219"; #define STR_SZ 1024 #define INOUTF_SZ 512 -#define EBUFF_SZ 512 +#define EBUFF_SZ 768 #define DEF_BLOCK_SIZE 512 #define DEF_BLOCKS_PER_TRANSFER 128 diff --git a/src/sg_get_lba_status.c b/src/sg_get_lba_status.c index 29e95115..7db694e4 100644 --- a/src/sg_get_lba_status.c +++ b/src/sg_get_lba_status.c @@ -32,7 +32,7 @@ * device. */ -static const char * version_str = "1.14 20180311"; +static const char * version_str = "1.15 20180425"; #ifndef UINT32_MAX #define UINT32_MAX ((uint32_t)-1) @@ -42,7 +42,6 @@ static const char * version_str = "1.14 20180311"; #define DEF_GLBAS_BUFF_LEN 24 static uint8_t glbasBuff[DEF_GLBAS_BUFF_LEN]; -static uint8_t * glbasBuffp = glbasBuff; static struct option long_options[] = { @@ -149,26 +148,28 @@ decode_lba_status_desc(const uint8_t * bp, uint64_t * slbap, int main(int argc, char * argv[]) { + bool do_16 = false; + bool do_32 = false; + bool do_raw = false; + bool o_readonly = false; int sg_fd, k, j, res, c, rlen, num_descs, completion_cond; int do_brief = 0; int do_hex = 0; - int64_t ll; - uint64_t lba = 0; + int ret = 0; + int maxlen = DEF_GLBAS_BUFF_LEN; + int rt = 0; + int verbose = 0; + uint8_t add_status = 0; /* keep gcc quiet */ uint64_t d_lba = 0; uint32_t d_blocks = 0; uint32_t element_id = 0; uint32_t scan_len = 0; - int maxlen = DEF_GLBAS_BUFF_LEN; - int rt = 0; - int verbose = 0; - bool do_16 = false; - bool do_32 = false; - bool do_raw = false; - bool o_readonly = false; + int64_t ll; + uint64_t lba = 0; const char * device_name = NULL; const uint8_t * bp; - int ret = 0; - uint8_t add_status = 0; /* keep gcc quiet */ + uint8_t * glbasBuffp = glbasBuff; + uint8_t * free_glbasBuffp = NULL; while (1) { int option_index = 0; @@ -271,7 +272,8 @@ main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } if (maxlen > DEF_GLBAS_BUFF_LEN) { - glbasBuffp = (uint8_t *)calloc(maxlen, 1); + glbasBuffp = (uint8_t *)sg_memalign(maxlen, 0, &free_glbasBuffp, + verbose > 3); if (NULL == glbasBuffp) { pr2serr("unable to allocate %d bytes on heap\n", maxlen); return SG_LIB_SYNTAX_ERROR; @@ -477,7 +479,7 @@ the_end: ret = SG_LIB_FILE_ERROR; } free_buff: - if (glbasBuffp && (glbasBuffp != glbasBuff)) - free(glbasBuffp); + if (free_glbasBuffp) + free(free_glbasBuffp); return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } diff --git a/src/sg_inq.c b/src/sg_inq.c index 57f234db..85dab11a 100644 --- a/src/sg_inq.c +++ b/src/sg_inq.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <stdbool.h> #include <string.h> +#include <errno.h> #include <ctype.h> #include <getopt.h> #define __STDC_FORMAT_MACROS 1 @@ -48,7 +49,7 @@ #include "sg_pt_nvme.h" #endif -static const char * version_str = "1.92 20180405"; /* SPC-5 rev 19 */ +static const char * version_str = "1.93 20180425"; /* SPC-5 rev 19 */ /* INQUIRY notes: * It is recommended that the initial allocation length given to a diff --git a/src/sg_logs.c b/src/sg_logs.c index c8086115..283a1831 100644 --- a/src/sg_logs.c +++ b/src/sg_logs.c @@ -34,7 +34,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.63 20180325"; /* spc5r19 + sbc4r11 */ +static const char * version_str = "1.65 20180501"; /* spc5r19 + sbc4r11 */ #define MX_ALLOC_LEN (0xfffc) #define SHORT_RESP_LEN 128 @@ -3042,17 +3042,22 @@ show_app_client_page(const uint8_t * resp, int len, const struct opts_t * op) static bool show_ie_page(const uint8_t * resp, int len, const struct opts_t * op) { - int k, num, extra, pc; + int k, num, param_len, pc; const uint8_t * bp; const char * cp; char str[PCB_STR_LEN]; char b[256]; char bb[32]; - bool full, decoded, has_header; + bool full, decoded; + bool has_header = false; bool is_smstr = op->lep ? (MVP_SMSTR & op->lep->flags) : (VP_SMSTR == op->vend_prod_num); full = ! op->do_temperature; + if ('\0' != t10_vendor_str[0]) { + if (0 != strcmp(vp_arr[VP_SMSTR].t10_vendorp, t10_vendor_str)) + is_smstr = false; /* Inquiry vendor string says not SmrtStor */ + } num = len - 4; bp = &resp[0] + 4; if (num < 4) { @@ -3063,54 +3068,63 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op) if (full) printf("Informational Exceptions page [0x2f]\n"); } - for (k = num, has_header = false; k > 0; k -= extra, bp += extra) { + for (k = num; k > 0; k -= param_len, bp += param_len) { if (k < 3) { printf("short Informational Exceptions page\n"); return false; } - extra = bp[3] + 4; + param_len = bp[3] + 4; pc = sg_get_unaligned_be16(bp + 0); if (op->filter_given) { if (pc != op->filter) continue; if (op->do_raw) { - dStrRaw(bp, extra); + dStrRaw(bp, param_len); break; } else if (op->do_hex) { - hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1)); + hex2stdout(bp, param_len, ((1 == op->do_hex) ? 1 : -1)); break; } } decoded = true; cp = NULL; + switch (pc) { case 0x0: - if (extra > 5) { + if (param_len > 5) { if (full) { printf(" IE asc = 0x%x, ascq = 0x%x", bp[4], bp[5]); if (bp[4] || bp[5]) if(sg_get_asc_ascq_str(bp[4], bp[5], sizeof(b), b)) printf("\n [%s]", b); } - if (extra > 6) { + if (param_len > 6) { if (bp[6] < 0xff) printf("\n Current temperature = %d C", bp[6]); else printf("\n Current temperature = <not available>"); - if (extra > 7) { + if (param_len > 7) { if (bp[7] < 0xff) printf("\n Threshold temperature = %d C " "[common extension]", bp[7]); else printf("\n Threshold temperature = <not " "available>"); - } + if ((param_len > 8) && (bp[8] >= bp[6])) { + if (bp[8] < 0xff) + printf("\n Maximum temperature = %d C " + "[(since new), extension]", bp[8]); + else + printf("\n Maximum temperature = <not " + "available>"); + } + } } decoded = true; } break; default: - if (! is_smstr) { + if ((! is_smstr) || (param_len < 24)) { decoded = false; break; } @@ -3170,8 +3184,8 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op) break; } break; - } - if (cp && (extra >= 24)) { + } /* end of switch statement */ + if (cp && (param_len >= 24)) { if (! has_header) { has_header = true; printf(" Has|Ever %% to worst %% Current " @@ -3188,14 +3202,14 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op) /* decoded = true; */ } else if ((! decoded) && full) { printf(" parameter code = 0x%x, contents in hex:\n", pc); - hex2stdout(bp, extra, 1); + hex2stdout(bp, param_len, 1); } printf("\n"); if (op->do_pcb) printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str))); if (op->filter_given) break; - } + } /* end of for loop */ return true; } diff --git a/src/sg_luns.c b/src/sg_luns.c index 20502ef5..cacb37c6 100644 --- a/src/sg_luns.c +++ b/src/sg_luns.c @@ -31,7 +31,7 @@ * and decodes the response. */ -static const char * version_str = "1.38 20180329"; +static const char * version_str = "1.39 20180425"; #define MAX_RLUNS_BUFF_LEN (1024 * 1024) #define DEF_RLUNS_BUFF_LEN (1024 * 8) @@ -380,6 +380,7 @@ main(int argc, char * argv[]) const char * device_name = NULL; const char * cp; uint8_t * reportLunsBuff = NULL; + uint8_t * free_reportLunsBuff = NULL; uint8_t lun_arr[8]; struct sg_simple_inquiry_resp sir; @@ -593,9 +594,10 @@ main(int argc, char * argv[]) if (0 == maxlen) maxlen = DEF_RLUNS_BUFF_LEN; - reportLunsBuff = (uint8_t *)calloc(1, maxlen); + reportLunsBuff = (uint8_t *)sg_memalign(maxlen, 0, &free_reportLunsBuff, + verbose > 3); if (NULL == reportLunsBuff) { - pr2serr("unable to malloc %d bytes\n", maxlen); + pr2serr("unable to sg_memalign %d bytes\n", maxlen); return SG_LIB_CAT_OTHER; } trunc = false; @@ -669,8 +671,8 @@ main(int argc, char * argv[]) } the_end: - if (reportLunsBuff) - free(reportLunsBuff); + if (free_reportLunsBuff) + free(free_reportLunsBuff); res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr("close error: %s\n", safe_strerror(-res)); diff --git a/src/sg_modes.c b/src/sg_modes.c index 0a839526..e680a153 100644 --- a/src/sg_modes.c +++ b/src/sg_modes.c @@ -550,7 +550,7 @@ static struct page_code_desc pc_desc_disk[] = { {0xa, 0x5, "IO advice hints grouping"}, /* added sbc4r06 */ {0xa, 0x6, "Background operation control"}, /* added sbc4r07 */ {0xa, 0xf1, "Parallel ATA control (SAT)"}, - {0xa, 0xf2, "Reserved (SATA control) (SAT)"}, +/* {0xa, 0xf2, "Reserved (SATA control) (SAT)"}, // proposed + dropped ?? */ {0xb, 0x0, "Medium types supported (obsolete)"}, {0xc, 0x0, "Notch and partition (obsolete)"}, {0xd, 0x0, "Power condition (obsolete, moved to 0x1a)"}, diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c index 8164dfb5..4e7f73d5 100644 --- a/src/sg_opcodes.c +++ b/src/sg_opcodes.c @@ -17,6 +17,7 @@ #include <stdbool.h> #include <string.h> #include <ctype.h> +#include <errno.h> #include <getopt.h> #ifdef HAVE_CONFIG_H @@ -30,7 +31,7 @@ #include "sg_pt.h" -static const char * version_str = "0.58 20180403"; /* spc5r14 */ +static const char * version_str = "0.59 20180428"; /* spc5r14 */ #define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ @@ -45,7 +46,7 @@ static const char * version_str = "0.58 20180403"; /* spc5r14 */ #define NAME_BUFF_SZ 128 -#define SEAGATE_READ_UDS_DATA_CMD 0xf7 /* may start reporting vendor cmds */ +#define SEAGATE_READ_UDS_DATA_CMD 0xf7 /* may start reporting vendor cmds */ static int peri_dtype = -1; /* ugly but not easy to pass to alpha compare */ @@ -907,12 +908,13 @@ list_one(uint8_t * rsoc_buff, int cd_len, int rep_opts, int main(int argc, char * argv[]) { - int sg_fd, cd_len, res, len, act_len, rq_len; + int sg_fd, cd_len, res, len, act_len, rq_len, vb; int rep_opts = 0; const char * cp; struct opts_t * op; const char * op_name; - uint8_t rsoc_buff[MX_ALLOC_LEN]; + uint8_t * rsoc_buff = NULL; + uint8_t * free_rsoc_buff = NULL; char buff[48]; char b[80]; struct sg_simple_inquiry_resp inq_resp; @@ -936,6 +938,7 @@ main(int argc, char * argv[]) pr2serr("Version string: %s\n", version_str); return 0; } + vb = op->verbose; if ((NULL == op->device_name) && (! op->do_enumerate)) { pr2serr("No DEVICE argument given\n"); @@ -976,7 +979,7 @@ main(int argc, char * argv[]) if (peri_dtype < 0) peri_dtype = 0; printf("SCSI command:"); - if (op->verbose) + if (vb) printf(" [opcode=0x%x, sa=0x%x, pdt=0x%x]\n", op->opcode, op->servact, peri_dtype); else @@ -990,18 +993,25 @@ main(int argc, char * argv[]) op_name = op->do_taskman ? "Report supported task management functions" : "Report supported operation codes"; + rsoc_buff = (uint8_t *)sg_memalign(MX_ALLOC_LEN, 0, &free_rsoc_buff, + vb > 3); + if (NULL == rsoc_buff) { + pr2serr("Unable to allocate memory\n"); + return sg_convert_errno(ENOMEM); + } + if (op->opcode < 0) { - if ((sg_fd = scsi_pt_open_device(op->device_name, 1 /* RO */, - op->verbose)) < 0) { + /* Try to open read-only */ + if ((sg_fd = scsi_pt_open_device(op->device_name, 1, vb)) < 0) { pr2serr("sg_opcodes: error opening file (ro): %s: %s\n", op->device_name, safe_strerror(-sg_fd)); - return SG_LIB_FILE_ERROR; + goto open_rw; } if (op->no_inquiry && (peri_dtype < 0)) pr2serr("--no-inquiry ignored because --pdt= not given\n"); if (op->no_inquiry && (peri_dtype >= 0)) ; - else if (0 == sg_simple_inquiry(sg_fd, &inq_resp, true, op->verbose)) { + else if (0 == sg_simple_inquiry(sg_fd, &inq_resp, true, vb)) { peri_dtype = inq_resp.peripheral_type; if (! (op->do_raw || op->no_inquiry)) { printf(" %.8s %.16s %.4s\n", inq_resp.vendor, @@ -1024,26 +1034,25 @@ main(int argc, char * argv[]) } } - if ((sg_fd = scsi_pt_open_device(op->device_name, 0 /* RW */, - op->verbose)) < 0) { +open_rw: + if ((sg_fd = scsi_pt_open_device(op->device_name, 0 /* RW */, vb)) < 0) { pr2serr("sg_opcodes: error opening file (rw): %s: %s\n", op->device_name, safe_strerror(-sg_fd)); return SG_LIB_FILE_ERROR; } if (op->opcode >= 0) rep_opts = ((op->servact >= 0) ? 2 : 1); - memset(rsoc_buff, 0, sizeof(rsoc_buff)); if (op->do_taskman) { rq_len = (op->do_repd ? 16 : 4); - res = do_rstmf(sg_fd, op->do_repd, rsoc_buff, - rq_len, &act_len, true, op->verbose); + res = do_rstmf(sg_fd, op->do_repd, rsoc_buff, rq_len, &act_len, true, + vb); } else { - rq_len = sizeof(rsoc_buff); + rq_len = MX_ALLOC_LEN; res = do_rsoc(sg_fd, op->do_rctd, rep_opts, op->opcode, op->servact, - rsoc_buff, rq_len, &act_len, true, op->verbose); + rsoc_buff, rq_len, &act_len, true, vb); } if (res) { - sg_get_category_sense_str(res, sizeof(b), b, op->verbose); + sg_get_category_sense_str(res, sizeof(b), b, vb); pr2serr("%s: %s\n", op_name, b); goto err_out; } @@ -1133,6 +1142,8 @@ main(int argc, char * argv[]) res = 0; err_out: + if (free_rsoc_buff) + free(free_rsoc_buff); scsi_pt_close_device(sg_fd); return res; } diff --git a/src/sg_raw.c b/src/sg_raw.c index 9dee2852..d480e6d0 100644 --- a/src/sg_raw.c +++ b/src/sg_raw.c @@ -37,7 +37,7 @@ #include "sg_pr2serr.h" #include "sg_unaligned.h" -#define SG_RAW_VERSION "0.4.24 (2018-03-02)" +#define SG_RAW_VERSION "0.4.25 (2018-04-25)" #define DEFAULT_TIMEOUT 20 #define MIN_SCSI_CDBSZ 6 @@ -576,7 +576,7 @@ fetch_dataout(struct opts_t * op, uint8_t ** free_buf, int * errp) pr2serr("sg_memalign: failed to get %d bytes of memory\n", op->dataout_len); if (errp) - *errp = SG_LIB_OS_BASE_ERR + ENOMEM; + *errp = sg_convert_errno(ENOMEM); goto bail; } @@ -728,7 +728,7 @@ main(int argc, char *argv[]) if (dinp == NULL) { pr2serr("sg_memalign: failed to get %d bytes of memory\n", din_len); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto done; } if (op->verbose > 2) diff --git a/src/sg_read.c b/src/sg_read.c index 9d9038cd..9326b180 100644 --- a/src/sg_read.c +++ b/src/sg_read.c @@ -53,7 +53,7 @@ #include "sg_pr2serr.h" -static const char * version_str = "1.30 20180219"; +static const char * version_str = "1.31 20180502"; #define DEF_BLOCK_SIZE 512 #define DEF_BLOCKS_PER_TRANSFER 128 @@ -368,7 +368,7 @@ static int sg_bread(int sg_fd, uint8_t * buff, int blocks, #define STR_SZ 1024 #define INF_SZ 512 -#define EBUFF_SZ 512 +#define EBUFF_SZ 768 int main(int argc, char * argv[]) diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c index c8673e61..ff10af92 100644 --- a/src/sg_read_attr.c +++ b/src/sg_read_attr.c @@ -12,6 +12,7 @@ #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <errno.h> #include <ctype.h> #include <getopt.h> #define __STDC_FORMAT_MACROS 1 @@ -36,7 +37,7 @@ * and decodes the response. Based on spc5r08.pdf */ -static const char * version_str = "1.08 20180219"; +static const char * version_str = "1.09 20180425"; #define MAX_RATTR_BUFF_LEN (1024 * 1024) #define DEF_RATTR_BUFF_LEN (1024 * 8) @@ -912,6 +913,7 @@ main(int argc, char * argv[]) const char * device_name = NULL; const char * fname = NULL; uint8_t * rabp = NULL; + uint8_t * free_rabp = NULL; struct opts_t opts; struct opts_t * op; char b[80]; @@ -1052,10 +1054,10 @@ main(int argc, char * argv[]) if (0 == op->maxlen) op->maxlen = DEF_RATTR_BUFF_LEN; - rabp = (uint8_t *)calloc(1, op->maxlen); + rabp = (uint8_t *)sg_memalign(op->maxlen, 0, &free_rabp, op->verbose > 3); if (NULL == rabp) { - pr2serr("unable to calloc %d bytes\n", op->maxlen); - return SG_LIB_CAT_OTHER; + pr2serr("unable to sg_memalign %d bytes\n", op->maxlen); + return sg_convert_errno(ENOMEM); } if (NULL == device_name) { @@ -1142,7 +1144,7 @@ close_then_end: ret = SG_LIB_FILE_ERROR; } clean_up: - if (rabp) - free(rabp); + if (free_rabp) + free(free_rabp); return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } diff --git a/src/sg_read_long.c b/src/sg_read_long.c index e214e5f6..1c278801 100644 --- a/src/sg_read_long.c +++ b/src/sg_read_long.c @@ -33,13 +33,13 @@ #include "sg_cmds_extra.h" #include "sg_pr2serr.h" -static const char * version_str = "1.24 20180219"; +static const char * version_str = "1.26 20180502"; #define MAX_XFER_LEN 10000 #define ME "sg_read_long: " -#define EBUFF_SZ 256 +#define EBUFF_SZ 512 static struct option long_options[] = { @@ -53,6 +53,7 @@ static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"xfer_len", required_argument, 0, 'x'}, + {"xfer-len", required_argument, 0, 'x'}, {0, 0, 0, 0}, }; diff --git a/src/sg_referrals.c b/src/sg_referrals.c index 96e1368e..83ab89e7 100644 --- a/src/sg_referrals.c +++ b/src/sg_referrals.c @@ -12,6 +12,7 @@ #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <errno.h> #include <getopt.h> #define __STDC_FORMAT_MACROS 1 #include <inttypes.h> @@ -34,7 +35,7 @@ * SCSI device. */ -static const char * version_str = "1.10 20180219"; /* sbc4r10 */ +static const char * version_str = "1.11 20180425"; /* sbc4r10 */ #define MAX_REFER_BUFF_LEN (1024 * 1024) #define DEF_REFER_BUFF_LEN 256 @@ -48,7 +49,6 @@ static const char * version_str = "1.10 20180219"; /* sbc4r10 */ #define TPGS_STATE_TRANSITIONING 0xf static uint8_t referralBuff[DEF_REFER_BUFF_LEN]; -static uint8_t * referralBuffp = referralBuff; static const char *decode_tpgs_state(const int st) { @@ -86,6 +86,7 @@ static struct option long_options[] = { {"lba", required_argument, 0, 'l'}, {"maxlen", required_argument, 0, 'm'}, {"one-segment", no_argument, 0, 's'}, + {"one_segment", no_argument, 0, 's'}, {"raw", no_argument, 0, 'r'}, {"readonly", no_argument, 0, 'R'}, {"verbose", no_argument, 0, 'v'}, @@ -182,6 +183,8 @@ main(int argc, char * argv[]) uint64_t lba = 0; const char * device_name = NULL; const uint8_t * bp; + uint8_t * referralBuffp = referralBuff; + uint8_t * free_referralBuffp = NULL; while (1) { int option_index = 0; @@ -255,10 +258,12 @@ main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } if (maxlen > DEF_REFER_BUFF_LEN) { - referralBuffp = (uint8_t *)calloc(maxlen, 1); + referralBuffp = (uint8_t *)sg_memalign(maxlen, 0, + &free_referralBuffp, + verbose > 3); if (NULL == referralBuffp) { pr2serr("unable to allocate %d bytes on heap\n", maxlen); - return SG_LIB_SYNTAX_ERROR; + return sg_convert_errno(ENOMEM); } } if (do_raw) { @@ -343,7 +348,7 @@ the_end: ret = SG_LIB_FILE_ERROR; } free_buff: - if (referralBuffp && (referralBuffp != referralBuff)) - free(referralBuffp); + if (free_referralBuffp) + free(free_referralBuffp); return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c index 2e8ef942..ce4078ad 100644 --- a/src/sg_rep_zones.c +++ b/src/sg_rep_zones.c @@ -12,6 +12,7 @@ #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <errno.h> #include <ctype.h> #include <getopt.h> #define __STDC_FORMAT_MACROS 1 @@ -35,7 +36,7 @@ * and decodes the response. Based on zbc-r02.pdf */ -static const char * version_str = "1.15 20180219"; +static const char * version_str = "1.16 20180425"; #define MAX_RZONES_BUFF_LEN (1024 * 1024) #define DEF_RZONES_BUFF_LEN (1024 * 8) @@ -287,6 +288,7 @@ main(int argc, char * argv[]) int64_t ll; const char * device_name = NULL; uint8_t * reportZonesBuff = NULL; + uint8_t * free_rzbp = NULL; uint8_t * bp; char b[80]; @@ -390,10 +392,11 @@ main(int argc, char * argv[]) if (0 == maxlen) maxlen = DEF_RZONES_BUFF_LEN; - reportZonesBuff = (uint8_t *)calloc(1, maxlen); + reportZonesBuff = (uint8_t *)sg_memalign(maxlen, 0, &free_rzbp, + verbose > 3); if (NULL == reportZonesBuff) { - pr2serr("unable to malloc %d bytes\n", maxlen); - return SG_LIB_CAT_OTHER; + pr2serr("unable to sg_memalign %d bytes\n", maxlen); + return sg_convert_errno(ENOMEM); } res = sg_ll_report_zones(sg_fd, st_lba, do_partial, reporting_opt, @@ -467,8 +470,8 @@ main(int argc, char * argv[]) } the_end: - if (reportZonesBuff) - free(reportZonesBuff); + if (free_rzbp) + free(free_rzbp); res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr("close error: %s\n", safe_strerror(-res)); diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c index e67a634c..38e5030b 100644 --- a/src/sg_sanitize.c +++ b/src/sg_sanitize.c @@ -661,7 +661,7 @@ main(int argc, char * argv[]) if (! got_stdin) close(infd); } - wBuff[0] = op->count & 0x1f;; + wBuff[0] = op->count & 0x1f; if (op->test) wBuff[0] |= ((op->test & 0x3) << 5); if (op->invert) diff --git a/src/sg_ses.c b/src/sg_ses.c index 41eea275..15d76295 100644 --- a/src/sg_ses.c +++ b/src/sg_ses.c @@ -28,9 +28,7 @@ #include "sg_cmds_basic.h" #include "sg_cmds_extra.h" #include "sg_unaligned.h" -#ifdef SG_LIB_WIN32 -#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */ -#endif +#include "sg_pt.h" #include "sg_pr2serr.h" /* @@ -38,10 +36,11 @@ * commands tailored for SES (enclosure) devices. */ -static const char * version_str = "2.35 20180305"; /* ses4r02 */ +static const char * version_str = "2.37 20180502"; /* ses4r02 */ #define MX_ALLOC_LEN ((64 * 1024) - 4) /* max allowable for big enclosures */ #define MX_ELEM_HDR 1024 +#define REQUEST_SENSE_RESP_SZ 252 #define DATA_IN_OFF 4 #define MIN_DATA_IN_SZ 8192 /* use max(MIN_DATA_IN_SZ, op->maxlen) for * the size of data_arr */ @@ -499,6 +498,7 @@ static struct element_type_t element_type_by_code = /* Many control element names below have "RQST" in front in drafts. These are for the Enclosure Control/Status diagnostic page */ static struct acronym2tuple ecs_a2t_arr[] = { + /* acron element_type start_byte start_bit num_bits */ {"ac_fail", UI_POWER_SUPPLY_ETC, 2, 4, 1, NULL}, {"ac_hi", UI_POWER_SUPPLY_ETC, 2, 6, 1, NULL}, {"ac_lo", UI_POWER_SUPPLY_ETC, 2, 7, 1, NULL}, @@ -557,7 +557,8 @@ static struct acronym2tuple ecs_a2t_arr[] = { {"fault", ARRAY_DEV_ETC, 3, 5, 1, NULL}, {"hotspare", ARRAY_DEV_ETC, 1, 5, 1, NULL}, {"hotswap", COOLING_ETC, 3, 7, 1, NULL}, - {"hotswap", ENC_SCELECTR_ETC, 3, 7, 1, NULL}, + {"hotswap", ENC_SCELECTR_ETC, 3, 7, 1, NULL}, /* status only */ + {"hw_reset", ENC_SCELECTR_ETC, 1, 2, 1, "hardware reset"}, /* 18-047r0 */ {"ident", DEVICE_ETC, 2, 1, 1, "flash LED"}, {"ident", ARRAY_DEV_ETC, 2, 1, 1, "flash LED"}, {"ident", POWER_SUPPLY_ETC, 1, 7, 1, "flash LED"}, @@ -652,7 +653,7 @@ static struct acronym2tuple ecs_a2t_arr[] = { {"remove", DEVICE_ETC, 2, 2, 1, NULL}, {"remove", ARRAY_DEV_ETC, 2, 2, 1, NULL}, {"remind", AUD_ALARM_ETC, 3, 4, 1, NULL}, - {"report", ENC_SCELECTR_ETC, 2, 0, 1, NULL}, + {"report", ENC_SCELECTR_ETC, 2, 0, 1, NULL}, /* status only */ {"report", SCC_CELECTR_ETC, 2, 0, 1, NULL}, {"report", SCSI_IPORT_ETC, 2, 0, 1, NULL}, {"report", SCSI_TPORT_ETC, 2, 0, 1, NULL}, @@ -661,7 +662,7 @@ static struct acronym2tuple ecs_a2t_arr[] = { {"rqst_override", TEMPERATURE_ETC, 3, 7, 1, "Request(ed) override"}, {"rrabort", ARRAY_DEV_ETC, 1, 0, 1, "rebuild/remap abort"}, {"rsvddevice", ARRAY_DEV_ETC, 1, 6, 1, "reserved device"}, - {"select_element", ENC_SCELECTR_ETC, 2, 0, 1, NULL}, + {"select_element", ENC_SCELECTR_ETC, 2, 0, 1, NULL}, /* control */ {"short_stat", SIMPLE_SUBENC_ETC, 3, 7, 8, "short enclosure status"}, {"size", NV_CACHE_ETC, 2, 7, 16, NULL}, {"speed_act", COOLING_ETC, 1, 2, 11, "actual speed (rpm / 10)"}, @@ -669,6 +670,7 @@ static struct acronym2tuple ecs_a2t_arr[] = { "0: leave; 1: lowest... 7: highest"}, {"size_mult", NV_CACHE_ETC, 1, 1, 2, NULL}, {"swap", -1, 0, 4, 1, NULL}, /* Reset swap */ + {"sw_reset", ENC_SCELECTR_ETC, 1, 3, 1, "software reset"},/* 18-047r0 */ {"temp", TEMPERATURE_ETC, 2, 7, 8, "(Requested) temperature"}, {"unlock", DOOR_ETC, 3, 0, 1, NULL}, {"undertemp_fail", TEMPERATURE_ETC, 3, 1, 1, "Undertemperature failure"}, @@ -738,6 +740,7 @@ static struct option long_options[] = { {"data", required_argument, 0, 'd'}, {"descriptor", required_argument, 0, 'D'}, {"dev-slot-num", required_argument, 0, 'x'}, + {"dev_slot_num", required_argument, 0, 'x'}, {"dsn", required_argument, 0, 'x'}, {"eiioe", required_argument, 0, 'E'}, {"enumerate", no_argument, 0, 'e'}, @@ -747,6 +750,7 @@ static struct option long_options[] = { {"hex", no_argument, 0, 'H'}, {"index", required_argument, 0, 'I'}, {"inner-hex", no_argument, 0, 'i'}, + {"inner_hex", no_argument, 0, 'i'}, {"join", no_argument, 0, 'j'}, {"list", no_argument, 0, 'l'}, {"nickid", required_argument, 0, 'N'}, @@ -758,6 +762,7 @@ static struct option long_options[] = { {"raw", no_argument, 0, 'r'}, {"readonly", no_argument, 0, 'R'}, {"sas-addr", required_argument, 0, 'A'}, + {"sas_addr", required_argument, 0, 'A'}, {"set", required_argument, 0, 'S'}, {"status", no_argument, 0, 's'}, {"verbose", no_argument, 0, 'v'}, @@ -1508,7 +1513,7 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[]) } if ((! (op->do_data && op->do_status)) && (NULL == op->dev_name)) { - pr2serr("missing DEVICE name!\n"); + pr2serr("missing DEVICE name!\n\n"); goto err_help; } return 0; @@ -1636,12 +1641,12 @@ match_last_ind_indiv(int index, const struct opts_t * op) /* Return of 0 -> success, SG_LIB_CAT_* positive values or -1 -> other * failures */ static int -do_senddiag(int sg_fd, void * outgoing_pg, int outgoing_len, bool noisy, - int verbose) +do_senddiag(struct sg_pt_base * ptvp, void * outgoing_pg, int outgoing_len, + bool noisy, int verbose) { const bool pf_bit = true; + int page_num, ret; const char * cp; - int page_num; if (outgoing_pg && (verbose > 2)) { page_num = ((const char *)outgoing_pg)[0]; @@ -1652,10 +1657,12 @@ do_senddiag(int sg_fd, void * outgoing_pg, int outgoing_len, bool noisy, pr2serr(" Send diagnostic command page number: 0x%x\n", page_num); } - return sg_ll_send_diag(sg_fd, 0 /* sf_code */, pf_bit, false /* sf_bit */, - false /* devofl_bit */, false /* unitofl_bit */, - 0 /* long_duration */, outgoing_pg, outgoing_len, - noisy, verbose); + ret = sg_ll_send_diag_pt(ptvp, 0 /* sf_code */, pf_bit, + false /* sf_bit */, false /* devofl_bit */, + false /* unitofl_bit */, 0 /* long_duration */, + outgoing_pg, outgoing_len, noisy, verbose); + clear_scsi_pt_obj(ptvp); + return ret; } /* Fetch diagnostic page name (status and/or control). Returns NULL if not @@ -1826,7 +1833,7 @@ find_join_row_cnst(const struct th_es_t * tesp, int index, /* Return of 0 -> success, SG_LIB_CAT_* positive values or -2 if response * had bad format, -1 -> other failures */ static int -do_rec_diag(int sg_fd, int page_code, uint8_t * rsp_buff, +do_rec_diag(struct sg_pt_base * ptvp, int page_code, uint8_t * rsp_buff, int rsp_buff_size, struct opts_t * op, int * rsp_lenp) { int k, d_len, rsp_len, res; @@ -1889,9 +1896,10 @@ do_rec_diag(int sg_fd, int page_code, uint8_t * rsp_buff, } if (vb > 1) pr2serr(" %s command for %s\n", rdr, cp); - res = sg_ll_receive_diag_v2(sg_fd, true /* pcv */, page_code, rsp_buff, + res = sg_ll_receive_diag_pt(ptvp, true /* pcv */, page_code, rsp_buff, rsp_buff_size, 0 /* default timeout */, &resid, ! op->quiet, vb); + clear_scsi_pt_obj(ptvp); decode: if (0 == res) { rsp_len = sg_get_unaligned_be16(rsp_buff + 2) + 4; @@ -2045,7 +2053,8 @@ truncated: * Returns total number of type descriptor headers written to 'tdhp' or -1 * if there is a problem */ static int -build_type_desc_hdr_arr(int fd, struct type_desc_hdr_t * tdhp, int max_elems, +build_type_desc_hdr_arr(struct sg_pt_base * ptvp, + struct type_desc_hdr_t * tdhp, int max_elems, uint32_t * generationp, struct enclosure_info * primary_ip, struct opts_t * op) @@ -2065,7 +2074,7 @@ build_type_desc_hdr_arr(int fd, struct type_desc_hdr_t * tdhp, int max_elems, ret = -1; goto the_end; } - res = do_rec_diag(fd, CONFIGURATION_DPC, config_dp_resp, op->maxlen, + res = do_rec_diag(ptvp, CONFIGURATION_DPC, config_dp_resp, op->maxlen, op, &resp_len); if (res) { pr2serr("%s: couldn't read config page, res=%d\n", __func__, res); @@ -4063,8 +4072,8 @@ err_with_fp: } static int -process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, - struct opts_t * op) +process_status_dpage(struct sg_pt_base * ptvp, int page_code, uint8_t * resp, + int resp_len, struct opts_t * op) { int j, num_ths; int ret = 0; @@ -4112,7 +4121,7 @@ process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, configuration_sdg(resp, resp_len); break; case ENC_STATUS_DPC: - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) { @@ -4130,7 +4139,7 @@ process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, enc_status_dp(tesp, ref_gen_code, resp, resp_len, op); break; case ARRAY_STATUS_DPC: - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) { @@ -4164,7 +4173,7 @@ process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, printf(" <empty>\n"); break; case THRESHOLD_DPC: - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) { @@ -4182,7 +4191,7 @@ process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, threshold_sdg(tesp, ref_gen_code, resp, resp_len, op); break; case ELEM_DESC_DPC: - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) { @@ -4209,7 +4218,7 @@ process_status_dpage(int sg_fd, int page_code, uint8_t * resp, int resp_len, resp[1] & 1, (resp[1] >> 1) & 0xff); break; case ADD_ELEM_STATUS_DPC: - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) { @@ -4255,7 +4264,7 @@ fini: /* Display "status" page or pages (if op->page_code==0xff) . data-in from * SES device or user provided (with --data= option). Return 0 for success */ static int -process_status_page_s(int sg_fd, struct opts_t * op) +process_status_page_s(struct sg_pt_base * ptvp, struct opts_t * op) { int page_code, ret, resp_len; uint8_t * resp = NULL; @@ -4276,10 +4285,10 @@ process_status_page_s(int sg_fd, struct opts_t * op) const int s_arr_sz = sizeof(supp_dpg_arr); memset(supp_dpg_arr, 0, s_arr_sz); - ret = do_rec_diag(sg_fd, SUPPORTED_DPC, resp, op->maxlen, op, + ret = do_rec_diag(ptvp, SUPPORTED_DPC, resp, op->maxlen, op, &resp_len); if (ret) /* SUPPORTED_DPC failed so try SUPPORTED_SES_DPC */ - ret = do_rec_diag(sg_fd, SUPPORTED_SES_DPC, resp, op->maxlen, op, + ret = do_rec_diag(ptvp, SUPPORTED_SES_DPC, resp, op->maxlen, op, &resp_len); if (ret) goto fini; @@ -4301,17 +4310,17 @@ process_status_page_s(int sg_fd, struct opts_t * op) } for (k = 0; k < n; ++k) { page_code = supp_dpg_arr[k]; - ret = do_rec_diag(sg_fd, page_code, resp, op->maxlen, op, + ret = do_rec_diag(ptvp, page_code, resp, op->maxlen, op, &resp_len); if (ret) goto fini; - ret = process_status_dpage(sg_fd, page_code, resp, resp_len, op); + ret = process_status_dpage(ptvp, page_code, resp, resp_len, op); } } else { /* asking for a specific page code */ - ret = do_rec_diag(sg_fd, page_code, resp, op->maxlen, op, &resp_len); + ret = do_rec_diag(ptvp, page_code, resp, op->maxlen, op, &resp_len); if (ret) goto fini; - ret = process_status_dpage(sg_fd, page_code, resp, resp_len, op); + ret = process_status_dpage(ptvp, page_code, resp, resp_len, op); } fini: @@ -4785,7 +4794,7 @@ join_juggle_aes(struct th_es_t * tesp, uint8_t * es_bp, const uint8_t * ed_bp, * stderr when op->verbose > 3. Returns 0 for success, any other return value * is an error. */ static int -join_work(int sg_fd, struct opts_t * op, bool display) +join_work(struct sg_pt_base * ptvp, struct opts_t * op, bool display) { bool broken_ei; int j, res, num_ths, mlen; @@ -4802,7 +4811,7 @@ join_work(int sg_fd, struct opts_t * op, bool display) struct th_es_t tes; memset(&primary_info, 0, sizeof(primary_info)); - num_ths = build_type_desc_hdr_arr(sg_fd, type_desc_hdr_arr, MX_ELEM_HDR, + num_ths = build_type_desc_hdr_arr(ptvp, type_desc_hdr_arr, MX_ELEM_HDR, &ref_gen_code, &primary_info, op); if (num_ths < 0) return num_ths; @@ -4819,7 +4828,7 @@ join_work(int sg_fd, struct opts_t * op, bool display) mlen = enc_stat_rsp_sz; if (mlen > op->maxlen) mlen = op->maxlen; - res = do_rec_diag(sg_fd, ENC_STATUS_DPC, enc_stat_rsp, mlen, op, + res = do_rec_diag(ptvp, ENC_STATUS_DPC, enc_stat_rsp, mlen, op, &enc_stat_rsp_len); if (res) return res; @@ -4838,7 +4847,7 @@ join_work(int sg_fd, struct opts_t * op, bool display) mlen = elem_desc_rsp_sz; if (mlen > op->maxlen) mlen = op->maxlen; - res = do_rec_diag(sg_fd, ELEM_DESC_DPC, elem_desc_rsp, mlen, op, + res = do_rec_diag(ptvp, ELEM_DESC_DPC, elem_desc_rsp, mlen, op, &elem_desc_rsp_len); if (0 == res) { if (elem_desc_rsp_len < 8) { @@ -4866,7 +4875,7 @@ join_work(int sg_fd, struct opts_t * op, bool display) mlen = add_elem_rsp_sz; if (mlen > op->maxlen) mlen = op->maxlen; - res = do_rec_diag(sg_fd, ADD_ELEM_STATUS_DPC, add_elem_rsp, mlen, op, + res = do_rec_diag(ptvp, ADD_ELEM_STATUS_DPC, add_elem_rsp, mlen, op, &add_elem_rsp_len); if (0 == res) { if (add_elem_rsp_len < 8) { @@ -4904,7 +4913,7 @@ join_work(int sg_fd, struct opts_t * op, bool display) mlen = threshold_rsp_sz; if (mlen > op->maxlen) mlen = op->maxlen; - res = do_rec_diag(sg_fd, THRESHOLD_DPC, threshold_rsp, mlen, op, + res = do_rec_diag(ptvp, THRESHOLD_DPC, threshold_rsp, mlen, op, &threshold_rsp_len); if (0 == res) { if (threshold_rsp_len < 8) { @@ -5013,7 +5022,7 @@ is_acronym_in_additional(const struct tuple_acronym_val * tavp) * Do clear/get/set (cgs) on Enclosure Control/Status page. Return 0 for ok * -2 for acronym not found, else -1 . */ static int -cgs_enc_ctl_stat(int sg_fd, struct join_row_t * jrp, +cgs_enc_ctl_stat(struct sg_pt_base * ptvp, struct join_row_t * jrp, const struct tuple_acronym_val * tavp, const struct opts_t * op, bool last) { @@ -5074,7 +5083,7 @@ cgs_enc_ctl_stat(int sg_fd, struct join_row_t * jrp, enc_stat_rsp[1] = op->byte1; len = sg_get_unaligned_be16(enc_stat_rsp + 2) + 4; if (last) { - ret = do_senddiag(sg_fd, enc_stat_rsp, len, ! op->quiet, + ret = do_senddiag(ptvp, enc_stat_rsp, len, ! op->quiet, op->verbose); if (ret) { pr2serr("couldn't send Enclosure Control page\n"); @@ -5089,7 +5098,7 @@ cgs_enc_ctl_stat(int sg_fd, struct join_row_t * jrp, * Do clear/get/set (cgs) on Threshold In/Out page. Return 0 for ok, * -2 for acronym not found, else -1 . */ static int -cgs_threshold(int sg_fd, const struct join_row_t * jrp, +cgs_threshold(struct sg_pt_base * ptvp, const struct join_row_t * jrp, const struct tuple_acronym_val * tavp, const struct opts_t * op, bool last) { @@ -5132,7 +5141,7 @@ cgs_threshold(int sg_fd, const struct join_row_t * jrp, threshold_rsp[1] = op->byte1; len = sg_get_unaligned_be16(threshold_rsp + 2) + 4; if (last) { - ret = do_senddiag(sg_fd, threshold_rsp, len, ! op->quiet, + ret = do_senddiag(ptvp, threshold_rsp, len, ! op->quiet, op->verbose); if (ret) { pr2serr("couldn't send Threshold Out page\n"); @@ -5194,7 +5203,7 @@ cgs_additional_el(const struct join_row_t * jrp, /* Do --clear, --get or --set . * Returns 0 for success, any other return value is an error. */ static int -ses_cgs(int sg_fd, const struct tuple_acronym_val * tavp, +ses_cgs(struct sg_pt_base * ptvp, const struct tuple_acronym_val * tavp, struct opts_t * op, bool last) { int ret, k, j, desc_len, dn_len; @@ -5203,7 +5212,7 @@ ses_cgs(int sg_fd, const struct tuple_acronym_val * tavp, const uint8_t * ed_bp; char b[64]; - if ((sg_fd < 0) && (GET_OPT != tavp->cgs_sel)) { + if ((NULL == ptvp) && (GET_OPT != tavp->cgs_sel)) { pr2serr("%s: --clear= and --set= only supported when DEVICE is " "given\n", __func__); return SG_LIB_SYNTAX_ERROR; @@ -5240,7 +5249,7 @@ ses_cgs(int sg_fd, const struct tuple_acronym_val * tavp, return -1; } if (false == join_done) { - ret = join_work(sg_fd, op, false); + ret = join_work(ptvp, op, false); if (ret) return ret; } @@ -5278,9 +5287,9 @@ ses_cgs(int sg_fd, const struct tuple_acronym_val * tavp, continue; } if (ENC_CONTROL_DPC == op->page_code) - ret = cgs_enc_ctl_stat(sg_fd, jrp, tavp, op, last); + ret = cgs_enc_ctl_stat(ptvp, jrp, tavp, op, last); else if (THRESHOLD_DPC == op->page_code) - ret = cgs_threshold(sg_fd, jrp, tavp, op, last); + ret = cgs_threshold(ptvp, jrp, tavp, op, last); else if (ADD_ELEM_STATUS_DPC == op->page_code) ret = cgs_additional_el(jrp, tavp, op); else { @@ -5322,20 +5331,20 @@ inconsistent: * the generation code. Returns 0 for success, any other return value is * an error. */ static int -ses_set_nickname(int sg_fd, struct opts_t * op) +ses_set_nickname(struct sg_pt_base * ptvp, struct opts_t * op) { int res, len; int resp_len = 0; uint8_t b[64]; const int control_plen = 0x24; - if (sg_fd < 0) { + if (NULL == ptvp) { pr2serr("%s: ignored when no device name\n", __func__); return 0; } memset(b, 0, sizeof(b)); /* Only after the generation code, offset 4 for 4 bytes */ - res = do_rec_diag(sg_fd, SUBENC_NICKNAME_DPC, b, 8, op, &resp_len); + res = do_rec_diag(ptvp, SUBENC_NICKNAME_DPC, b, 8, op, &resp_len); if (res) { pr2serr("%s: Subenclosure nickname status page, res=%d\n", __func__, res); @@ -5360,7 +5369,7 @@ ses_set_nickname(int sg_fd, struct opts_t * op) if (len > 32) len = 32; memcpy(b + 8, op->nickname_str, len); - return do_senddiag(sg_fd, b, control_plen + 4, ! op->quiet, + return do_senddiag(ptvp, b, control_plen + 4, ! op->quiet, op->verbose); } @@ -5466,7 +5475,7 @@ int main(int argc, char * argv[]) { bool have_cgs = false; - int k, d_len, res, vb; + int k, d_len, res, resid, vb; int sg_fd = -1; int pd_type = 0; int ret = 0; @@ -5479,10 +5488,10 @@ main(int argc, char * argv[]) uint8_t * free_elem_desc_rsp = NULL; uint8_t * free_add_elem_rsp = NULL; uint8_t * free_threshold_rsp = NULL; + struct sg_pt_base * ptvp = NULL; struct tuple_acronym_val tav_arr[CGS_CL_ARR_MAX_SZ]; - struct sg_simple_inquiry_resp inq_resp; char buff[128]; - char b[80]; + char b[128]; op = &opts; memset(op, 0, sizeof(*op)); @@ -5610,46 +5619,131 @@ main(int argc, char * argv[]) if (sg_fd < 0) { pr2serr("open error: %s: %s\n", op->dev_name, safe_strerror(-sg_fd)); - ret = SG_LIB_FILE_ERROR; + ret = sg_convert_errno(-sg_fd); + goto err_out; + } + ptvp = construct_scsi_pt_obj_with_fd(sg_fd, vb); + if (NULL == ptvp) { + pr2serr("construct pt_base failed, probably out of memory\n"); + ret = sg_convert_errno(ENOMEM); goto err_out; } if (! (op->do_raw || have_cgs || (op->do_hex > 2))) { - if ((ret = sg_simple_inquiry(sg_fd, &inq_resp, ! op->quiet, vb))) { + if ((ret = sg_ll_inquiry_pt(ptvp, false, 0, enc_stat_rsp, 36, + 0, &resid, ! op->quiet, vb))) { pr2serr("%s doesn't respond to a SCSI INQUIRY\n", op->dev_name); goto err_out; } else { - printf(" %.8s %.16s %.4s\n", inq_resp.vendor, - inq_resp.product, inq_resp.revision); - pd_type = inq_resp.peripheral_type; + if (resid > 0) + pr2serr("Short INQUIRY response, not looking good\n"); + printf(" %.8s %.16s %.4s\n", enc_stat_rsp + 8, + enc_stat_rsp + 16, enc_stat_rsp + 32); + pd_type = 0x1f & enc_stat_rsp[0]; cp = sg_get_pdt_str(pd_type, sizeof(buff), buff); if (0xd == pd_type) { if (vb) printf(" enclosure services device\n"); - } else if (0x40 & inq_resp.byte_6) + } else if (0x40 & enc_stat_rsp[6]) printf(" %s device has EncServ bit set\n", cp); - else - printf(" %s device (not an enclosure)\n", cp); + else { + if (0 != memcmp("NVMe", enc_stat_rsp + 8, 4)) + printf(" %s device (not an enclosure)\n", cp); + } } + clear_scsi_pt_obj(ptvp); + /* finished using enc_stat_rsp so clear back to zero */ + memset(enc_stat_rsp, 0, enc_stat_rsp_sz); } } else if (op->do_control) { pr2serr("Cannot do SCSI Send diagnostic command without a DEVICE\n"); return SG_LIB_SYNTAX_ERROR; } +#if (HAVE_NVME && (! IGNORE_NVME)) + if (ptvp && pt_device_is_nvme(ptvp) && (enc_stat_rsp_sz > 4095)) { + /* Fetch VPD 0xde (vendor specific: sg3_utils) for Identify ctl */ + ret = sg_ll_inquiry_pt(ptvp, true, 0xde, enc_stat_rsp, 4096, 0, + &resid, ! op->quiet, vb); + if (ret) { + if (vb) + pr2serr("Fetch VPD page 0xde (NVMe Identify ctl) failed, " + "continue\n"); + } else if (resid > 0) { + if (vb) + pr2serr("VPD page 0xde (NVMe Identify ctl) less than 4096 " + "bytes, continue\n"); + } else { + uint8_t nvmsr; + uint16_t oacs; + + nvmsr = enc_stat_rsp[253]; + oacs = sg_get_unaligned_le16(enc_stat_rsp + 256); + if (vb > 3) + pr2serr("NVMe Identify ctl response: nvmsr=%u, oacs=0x%x\n", + nvmsr, oacs); + if (! ((0x2 & nvmsr) && (0x40 & oacs))) { + pr2serr(">>> Warning: A NVMe enclosure needs both the " + "enclosure bit and support for\n"); + pr2serr(">>> MI Send+Receive commands bit set; current " + "state: %s, %s\n", (0x2 & nvmsr) ? "set" : "clear", + (0x40 & oacs) ? "set" : "clear"); + } + } + clear_scsi_pt_obj(ptvp); + memset(enc_stat_rsp, 0, 4096); + } +#endif + + if (ptvp) { + ret = sg_ll_request_sense_pt(ptvp, false, enc_stat_rsp, + REQUEST_SENSE_RESP_SZ, ! op->quiet, vb); + if (0 == ret) { + int sense_len = REQUEST_SENSE_RESP_SZ - get_scsi_pt_resid(ptvp); + struct sg_scsi_sense_hdr ssh; + + if ((sense_len > 7) && sg_scsi_normalize_sense(enc_stat_rsp, + sense_len, &ssh)) { + const char * aa_str = sg_get_asc_ascq_str(ssh.asc, ssh.ascq, + sizeof(b), b); + + /* Ignore the possibility that multiple UAs queued up */ + if (SPC_SK_UNIT_ATTENTION == ssh.sense_key) + pr2serr("Unit attention detected: %s\n ... continue\n", + aa_str); + else { + if (vb) { + pr2serr("Request Sense near startup detected " + "something:\n"); + pr2serr(" Sense key: %s, additional: %s\n ... " + "continue\n", + sg_get_sense_key_str(ssh.sense_key, + sizeof(buff), buff), aa_str); + } + } + } + } else { + if (vb) + pr2serr("Request sense failed (res=%d), most likely " + " problems ahead\n", ret); + } + clear_scsi_pt_obj(ptvp); + memset(enc_stat_rsp, 0, REQUEST_SENSE_RESP_SZ); + } + if (op->nickname_str) - ret = ses_set_nickname(sg_fd, op); + ret = ses_set_nickname(ptvp, op); else if (have_cgs) { for (k = 0, tavp = tav_arr, cgs_clp = op->cgs_cl_arr; k < op->num_cgs; ++k, ++tavp, ++cgs_clp) { - ret = ses_cgs(sg_fd, tavp, op, cgs_clp->last_cs); + ret = ses_cgs(ptvp, tavp, op, cgs_clp->last_cs); if (ret) break; } } else if (op->do_join) - ret = join_work(sg_fd, op, true); + ret = join_work(ptvp, op, true); else if (op->do_status) - ret = process_status_page_s(sg_fd, op); + ret = process_status_page_s(ptvp, op); else { /* control page requested */ op->data_arr[0] = op->page_code; op->data_arr[1] = op->byte1; @@ -5659,7 +5753,7 @@ main(int argc, char * argv[]) case ENC_CONTROL_DPC: /* Enclosure Control diagnostic page [0x2] */ printf("Sending Enclosure Control [0x%x] page, with page " "length=%d bytes\n", op->page_code, op->arr_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Enclosure Control page\n"); goto err_out; @@ -5668,7 +5762,7 @@ main(int argc, char * argv[]) case STRING_DPC: /* String Out diagnostic page [0x4] */ printf("Sending String Out [0x%x] page, with page length=%d " "bytes\n", op->page_code, op->arr_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send String Out page\n"); goto err_out; @@ -5677,7 +5771,7 @@ main(int argc, char * argv[]) case THRESHOLD_DPC: /* Threshold Out diagnostic page [0x5] */ printf("Sending Threshold Out [0x%x] page, with page length=%d " "bytes\n", op->page_code, op->arr_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Threshold Out page\n"); goto err_out; @@ -5686,7 +5780,7 @@ main(int argc, char * argv[]) case ARRAY_CONTROL_DPC: /* Array control diagnostic page [0x6] */ printf("Sending Array Control [0x%x] page, with page " "length=%d bytes\n", op->page_code, op->arr_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Array Control page\n"); goto err_out; @@ -5695,7 +5789,7 @@ main(int argc, char * argv[]) case SUBENC_STRING_DPC: /* Subenclosure String Out page [0xc] */ printf("Sending Subenclosure String Out [0x%x] page, with page " "length=%d bytes\n", op->page_code, op->arr_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Subenclosure String Out page\n"); goto err_out; @@ -5706,7 +5800,7 @@ main(int argc, char * argv[]) "page length=%d bytes\n", op->page_code, d_len); printf(" Perhaps it would be better to use the sg_ses_microcode " "utility\n"); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Download Microcode Control page\n"); goto err_out; @@ -5715,7 +5809,7 @@ main(int argc, char * argv[]) case SUBENC_NICKNAME_DPC: /* Subenclosure Nickname Control [0xf] */ printf("Sending Subenclosure Nickname Control [0x%x] page, with " "page length=%d bytes\n", op->page_code, d_len); - ret = do_senddiag(sg_fd, op->data_arr, d_len, ! op->quiet, vb); + ret = do_senddiag(ptvp, op->data_arr, d_len, ! op->quiet, vb); if (ret) { pr2serr("couldn't send Subenclosure Nickname Control page\n"); goto err_out; @@ -5754,6 +5848,8 @@ err_out: ret = SG_LIB_FILE_ERROR; } early_out: + if (ptvp) + destruct_scsi_pt_obj(ptvp); if ((0 == vb) && (! op->quiet)) { if (! sg_if_can2stderr("sg_ses failed: ", ret)) pr2serr("Some error occurred, try again with '-v' or '-vv' for " diff --git a/src/sg_stream_ctl.c b/src/sg_stream_ctl.c index e278e4a2..f2372ed7 100644 --- a/src/sg_stream_ctl.c +++ b/src/sg_stream_ctl.c @@ -33,7 +33,7 @@ * to the given SCSI device. Based on sbc4r15.pdf . */ -static const char * version_str = "1.02 20180219"; +static const char * version_str = "1.03 20180427"; #define STREAM_CONTROL_SA 0x14 #define GET_STREAM_STATUS_SA 0x16 @@ -166,7 +166,10 @@ sg_ll_get_stream_status(int sg_fd, uint16_t s_str_id, uint8_t * resp, } /* Invokes a SCSI STREAM CONTROL command (SBC-4). Return of 0 -> success, - * various SG_LIB_CAT_* positive values or -1 -> other errors */ + * various SG_LIB_CAT_* positive values or -1 -> other errors. + * N.B. The is a device modifying command that is SERVICE ACTION IN(16) + * command since it has data-in buffer that for open returns the + * ASSIGNED_STR_ID field . */ static int sg_ll_stream_control(int sg_fd, uint32_t str_ctl, uint16_t str_id, uint8_t * resp, uint32_t alloc_len, int * residp, @@ -202,12 +205,9 @@ sg_ll_stream_control(int sg_fd, uint32_t str_ctl, uint16_t str_id, res = do_scsi_pt(ptvp, -1, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, cmd_name, res, alloc_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) { + 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: @@ -378,7 +378,7 @@ main(int argc, char * argv[]) arr = sg_memalign(pg_sz, pg_sz, &free_arr, verbose > 3); if (NULL == arr) { pr2serr("Unable to allocate space for response\n"); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return sg_convert_errno(ENOMEM); } resid = 0; diff --git a/src/sg_test_rwbuf.c b/src/sg_test_rwbuf.c index 7bd5d962..c680ae4b 100644 --- a/src/sg_test_rwbuf.c +++ b/src/sg_test_rwbuf.c @@ -29,6 +29,7 @@ #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <errno.h> #include <getopt.h> #include <sys/ioctl.h> #include <sys/types.h> @@ -44,7 +45,7 @@ #include "sg_pr2serr.h" -static const char * version_str = "1.15 20180219"; +static const char * version_str = "1.16 20180428"; #define BPI (signed)(sizeof(int)) @@ -64,6 +65,7 @@ static int base = 0x12345678; static int buf_capacity = 0; static int buf_granul = 255; static uint8_t *cmpbuf = NULL; +static uint8_t *free_cmpbuf = NULL; /* Options */ @@ -229,7 +231,9 @@ int read_buffer (int sg_fd, unsigned ssize) int res, k; uint8_t rb_cdb[] = {READ_BUFFER, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int bufSize = ssize + addread; - uint8_t * rbBuff = (uint8_t *)malloc(bufSize); + uint8_t * free_rbBuff = NULL; + uint8_t * rbBuff = (uint8_t *)sg_memalign(bufSize, 0, &free_rbBuff, + false); uint8_t sense_buffer[32]; struct sg_io_hdr io_hdr; @@ -280,7 +284,8 @@ int read_buffer (int sg_fd, unsigned ssize) } res = do_checksum((int*)rbBuff, ssize, false); - free(rbBuff); + if (free_rbBuff) + free(free_rbBuff); return res; } @@ -288,7 +293,9 @@ int write_buffer (int sg_fd, unsigned ssize) { uint8_t wb_cdb[] = {WRITE_BUFFER, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int bufSize = ssize + addwrite; - uint8_t * wbBuff = (uint8_t *)malloc(bufSize); + uint8_t * free_wbBuff = NULL; + uint8_t * wbBuff = (uint8_t *)sg_memalign(bufSize, 0, &free_wbBuff, + false); uint8_t sense_buffer[32]; struct sg_io_hdr io_hdr; int k, res; @@ -340,7 +347,8 @@ int write_buffer (int sg_fd, unsigned ssize) free(wbBuff); return res; } - free(wbBuff); + if (free_wbBuff) + free(free_wbBuff); return res; } @@ -511,7 +519,7 @@ int main (int argc, char * argv[]) goto err_out; } - cmpbuf = (uint8_t *)malloc(size); + cmpbuf = (uint8_t *)sg_memalign(size, 0, &free_cmpbuf, false); for (k = 0; k < times; ++k) { ret = write_buffer (sg_fd, size); if (ret) { @@ -526,8 +534,8 @@ int main (int argc, char * argv[]) } err_out: - if (cmpbuf) - free(cmpbuf); + if (free_cmpbuf) + free(free_cmpbuf); res = close(sg_fd); if (res < 0) { perror(ME "close error"); diff --git a/src/sg_timestamp.c b/src/sg_timestamp.c index 17105976..976bca56 100644 --- a/src/sg_timestamp.c +++ b/src/sg_timestamp.c @@ -35,7 +35,7 @@ * to the given SCSI device. Based on spc5r07.pdf . */ -static const char * version_str = "1.07 20180219"; +static const char * version_str = "1.08 20180502"; #define REP_TIMESTAMP_CMDLEN 12 #define SET_TIMESTAMP_CMDLEN 12 @@ -53,8 +53,12 @@ uint8_t d_buff[256]; static struct option long_options[] = { + {"elapsed", no_argument, 0, 'e'}, {"help", no_argument, 0, 'h'}, + {"hex", no_argument, 0, 'H'}, {"milliseconds", required_argument, 0, 'm'}, + {"no_timestamp", no_argument, 0, 'N'}, + {"no-timestamp", no_argument, 0, 'N'}, {"origin", no_argument, 0, 'o'}, {"raw", no_argument, 0, 'r'}, {"readonly", no_argument, 0, 'R'}, @@ -79,20 +83,38 @@ static const char * ts_origin_arr[] = { static void -usage() +usage(int num) { + if (num > 1) + goto page2; + pr2serr("Usage: " - "sg_timestamp [--help] [--milliseconds=MS] [--origin] [--raw]\n" - " [--readonly] [--seconds=SEC] [--srep] " - "[--verbose]\n" - " [--version] DEVICE\n"); + "sg_timestamp [--elapsed] [--help] [--hex] [--milliseconds=MS]\n" + " [--no-timestamp] [--origin] [--raw] " + "[--readonly]\n" + " [--seconds=SEC] [--srep] [--verbose] " + "[--version]\n" + " DEVICE\n" + ); pr2serr(" where:\n" - " --help|-h print out usage message\n" + " --elapsed|-e show time as '<n> days hh.mm.ss.xxx' " + "where\n" + " '.xxx' is the remainder milliseconds. " + "Don't show\n" + " '<n> days' if <n> is 0 (unless '-e' " + "given twice)\n" + " --help|-h print out usage message, use twice for " + "examples\n" + " --hex|-H output response in ASCII hexadecimal\n" " --milliseconds=MS|-m MS set timestamp to MS " "milliseconds since\n" " 1970-01-01 00:00:00 UTC\n" + " --no-timestamp|-N suppress output of timestamp\n" " --origin|-o show Report timestamp origin " "(def: don't)\n" + " used twice outputs value of field\n" + " 0: power up or hard reset; 2: SET " + "TIMESTAMP\n" " --raw|-r output Report timestamp response to " "stdout in\n" " binary\n" @@ -106,17 +128,62 @@ usage() " milliseconds)\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" - "Performs a SCSI REPORT TIMESTAMP or SET TIMESTAMP command. " + ); + pr2serr("Performs a SCSI REPORT TIMESTAMP or SET TIMESTAMP command. " "The timestamp\nis SET if either the --milliseconds=MS or " "--seconds=SEC option is given,\notherwise the existing " - "timestamp is reported. The DEVICE stores the\ntimestamp as " - "the number of milliseconds since power up (or reset) or\n" - "since 1970-01-01 00:00:00 UTC which also happens to be the " - "time 'epoch'\nof Unix machines. The 'date +%%s' command in " + "timestamp is reported in milliseconds. The\nDEVICE stores " + "the timestamp as the number of milliseconds since power up\n" + "(or reset) or since 1970-01-01 00:00:00 UTC which also " + "happens to\nbe the time 'epoch'of Unix machines.\n\n" + "Use '-hh' (the '-h' option twice) for examples.\n" +#if 0 + "The 'date +%%s' command in " "Unix returns the number of\nseconds since the epoch. To " "convert a reported timestamp (in seconds since\nthe epoch) " "to a more readable form use " - "'date --date='@<secs_since_epoch>' .\n"); + "'date --date=@<secs_since_epoch>' .\n" +#endif + ); + return; +page2: + pr2serr("sg_timestamp examples:\n" + "It is possible that the target device containing a SCSI " + "Logical Unit (LU)\nhas a battery (or supercapacitor) to " + "keep its RTC (real time clock)\nticking during a power " + "outage. More likely it doesn't and its RTC is\ncleared to " + "zero after a power cycle or hard reset.\n\n" + "Either way REPORT TIMESTAMP returns a 48 bit counter value " + "whose unit is\na millisecond. A heuristic to determine if a " + "date or elapsed time is\nbeing returned is to choose a date " + "like 1 January 2000 which is 30 years\nafter the Unix epoch " + "(946,684,800,000 milliseconds) and values less than\nthat are " + "elapsed times and greater are timestamps. Observing the " + "TIMESTAMP\nORIGIN field of REPORT TIMESTAMP is a better " + "method:\n\n" + ); + pr2serr(" $ sg_timestamp -o -N /dev/sg1\n" + "Device clock initialized to zero at power on or by hard " + "reset\n" + " $ sg_timestamp -oo -N /dev/sg1\n" + "0\n\n" + " $ sg_timestamp /dev/sg1\n" + "3984499\n" + " $ sg_timestamp --elapsed /dev/sg1\n" + "01:06:28.802\n\n" + "The last output indicates an elapsed time of 1 hour, 6 minutes " + "and 28.802\nseconds. Next set the clock to the current time:\n\n" + " $ sg_timestamp --seconds=`date +%%s` /dev/sg1\n\n" + " $ sg_timestamp -o -N /dev/sg1\n" + "Device clock initialized by SET TIMESTAMP command\n\n" + "Now show that as an elapsed time:\n\n" + " $ sg_timestamp -e /dev/sg1\n" + "17652 days 20:53:22.545\n\n" + "That is over 48 years worth of days. Lets try again as a " + "data-time\nstamp in UTC:\n\n" + " $ date -u -R --date=@`sg_timestamp -S /dev/sg1`\n" + "Tue, 01 May 2018 20:56:38 +0000\n" + ); } /* Invokes a SCSI REPORT TIMESTAMP command. Return of 0 -> success, @@ -244,12 +311,16 @@ dStrRaw(const uint8_t * str, int len) int main(int argc, char * argv[]) { - bool do_origin = false; bool do_srep = false; bool do_raw = false; + bool no_timestamp = false; bool readonly = false; bool secs_given = false; int sg_fd, res, c; + int elapsed = 0; + int do_origin = 0; + int do_help = 0; + int do_hex = 0; int do_set = 0; int ret = 0; int verbose = 0; @@ -262,16 +333,22 @@ main(int argc, char * argv[]) while (1) { int option_index = 0; - c = getopt_long(argc, argv, "hm:orRs:SvV", long_options, + c = getopt_long(argc, argv, "ehHm:NorRs:SvV", long_options, &option_index); if (c == -1) break; switch (c) { + case 'e': + ++elapsed; + break; case 'h': case '?': - usage(); - return 0; + ++do_help; + break; + case 'H': + ++do_hex; + break; case 'm': ll = sg_get_llnum(optarg); if (-1 == ll) { @@ -281,8 +358,11 @@ main(int argc, char * argv[]) msecs = (uint64_t)ll; ++do_set; break; + case 'N': + no_timestamp = true; + break; case 'o': - do_origin = true; + ++do_origin; break; case 'r': do_raw = true; @@ -311,7 +391,7 @@ main(int argc, char * argv[]) return 0; default: pr2serr("unrecognised option code 0x%x ??\n", c); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } } @@ -323,21 +403,25 @@ main(int argc, char * argv[]) if (optind < argc) { for (; optind < argc; ++optind) pr2serr("Unexpected extra argument: %s\n", argv[optind]); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } } + if (do_help) { + usage(do_help); + return 0; + } if (do_set > 1) { pr2serr("either --milliseconds=MS or --seconds=SEC may be given, " "not both\n"); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } if (NULL == device_name) { - pr2serr("missing device name!\n"); - usage(); + pr2serr("missing device name!\n\n"); + usage(1); return SG_LIB_SYNTAX_ERROR; } @@ -359,17 +443,42 @@ main(int argc, char * argv[]) if (0 == res) { if (do_raw) dStrRaw(d_buff, 12); + else if (do_hex) + hex2stderr(d_buff, 12, 1); else { int len = sg_get_unaligned_be16(d_buff + 0); + if (len < 8) pr2serr("timestamp parameter data length too short, " "expect >= 10, got %d\n", len + 2); else { - if (do_origin) - printf("Device clock %s\n", - ts_origin_arr[0x7 & d_buff[2]]); - msecs = sg_get_unaligned_be48(d_buff + 4); - printf("%" PRIu64 "\n", do_srep ? (msecs / 1000) : msecs); + if (do_origin) { + if (1 == do_origin) + printf("Device clock %s\n", + ts_origin_arr[0x7 & d_buff[2]]); + else if (2 == do_origin) + printf("%d\n", 0x7 & d_buff[2]); + else + printf("TIMESTAMP_ORIGIN=%d\n", 0x7 & d_buff[2]); + } + if (! no_timestamp) { + msecs = sg_get_unaligned_be48(d_buff + 4); + if (elapsed) { + int days = (int)(msecs / 1000 / 60 / 60 / 24); + int hours = (int)(msecs / 1000 / 60 / 60 % 24); + int mins = (int)(msecs / 1000 / 60 % 60); + int secs_in_min =(int)( msecs / 1000 % 60); + int rem_msecs = (int)(msecs % 1000); + + if ((elapsed > 1) || (days > 0)) + printf("%d day%s ", days, + ((1 == days) ? "" : "s")); + printf("%02d:%02d:%02d.%03d\n", hours, mins, + secs_in_min, rem_msecs); + } else + printf("%" PRIu64 "\n", do_srep ? + (msecs / 1000) : msecs); + } } } } diff --git a/src/sg_vpd.c b/src/sg_vpd.c index 1aad48df..2e2d7081 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -856,6 +856,9 @@ decode_mode_policy_vpd(uint8_t * buff, int len, int do_hex) printf(", subpage code: 0x%x\n", bp[1]); else printf("\n"); + if ((0 == k) && (0x3f == (0x3f & bp[0])) && (0xff == bp[1])) + printf(" therefore the policy applies to all modes pages " + "and subpages\n"); printf(" MLUS=%d, Policy: %s\n", !!(bp[2] & 0x80), mode_page_policy_arr[bp[2] & 0x3]); } diff --git a/src/sg_write_long.c b/src/sg_write_long.c index 8b01c1a7..b6f9e694 100644 --- a/src/sg_write_long.c +++ b/src/sg_write_long.c @@ -35,20 +35,21 @@ #include "sg_cmds_extra.h" #include "sg_pr2serr.h" -static const char * version_str = "1.16 20180219"; +static const char * version_str = "1.17 20180502"; -#define MAX_XFER_LEN 10000 +#define MAX_XFER_LEN (15 * 1024) /* #define SG_DEBUG */ #define ME "sg_write_long: " -#define EBUFF_SZ 256 +#define EBUFF_SZ 512 static struct option long_options[] = { {"16", no_argument, 0, 'S'}, {"cor_dis", no_argument, 0, 'c'}, + {"cor-dis", no_argument, 0, 'c'}, {"help", no_argument, 0, 'h'}, {"in", required_argument, 0, 'i'}, {"lba", required_argument, 0, 'l'}, @@ -56,7 +57,9 @@ static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"wr_uncor", no_argument, 0, 'w'}, + {"wr-uncor", no_argument, 0, 'w'}, {"xfer_len", required_argument, 0, 'x'}, + {"xfer-len", required_argument, 0, 'x'}, {0, 0, 0, 0}, }; @@ -111,6 +114,7 @@ main(int argc, char * argv[]) const char * device_name = NULL; uint8_t * writeLongBuff = NULL; void * rawp = NULL; + uint8_t * free_rawp = NULL; const char * ten_or; char file_name[256]; char b[80]; @@ -209,9 +213,9 @@ main(int argc, char * argv[]) pr2serr(">>> warning: when '--wr_uncor' given '-in=' is " "ignored\n"); } else { - if (NULL == (rawp = malloc(MAX_XFER_LEN))) { + if (NULL == (rawp = sg_memalign(MAX_XFER_LEN, 0, &free_rawp, false))) { pr2serr(ME "out of memory\n"); - ret = SG_LIB_FILE_ERROR; + ret = sg_convert_errno(ENOMEM); goto err_out; } writeLongBuff = (uint8_t *)rawp; @@ -279,8 +283,8 @@ main(int argc, char * argv[]) } err_out: - if (rawp) - free(rawp); + if (free_rawp) + free(free_rawp); res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr("close error: %s\n", safe_strerror(-res)); diff --git a/src/sg_write_same.c b/src/sg_write_same.c index d2176395..2d6d241a 100644 --- a/src/sg_write_same.c +++ b/src/sg_write_same.c @@ -31,7 +31,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.21 20180219"; +static const char * version_str = "1.22 20180425"; #define ME "sg_write_same: " @@ -317,6 +317,7 @@ main(int argc, char * argv[]) const char * device_name = NULL; struct opts_t * op; uint8_t * wBuff = NULL; + uint8_t * free_wBuff = NULL; char ebuff[EBUFF_SZ]; char b[80]; uint8_t resp_buff[RCAP16_RESP_LEN]; @@ -550,11 +551,11 @@ main(int argc, char * argv[]) ret = SG_LIB_SYNTAX_ERROR; goto err_out; } - wBuff = (uint8_t*)calloc(op->xfer_len, 1); + wBuff = (uint8_t *)sg_memalign(op->xfer_len, 0, &free_wBuff, vb > 3); if (NULL == wBuff) { - pr2serr("unable to allocate %d bytes of memory with calloc()\n", - op->xfer_len); - ret = SG_LIB_SYNTAX_ERROR; + pr2serr("unable to allocate %d bytes of memory with " + "sg_memalign()\n", op->xfer_len); + ret = sg_convert_errno(ENOMEM); goto err_out; } if (op->ifilename[0]) { @@ -610,8 +611,8 @@ main(int argc, char * argv[]) } err_out: - if (wBuff) - free(wBuff); + if (free_wBuff) + free(free_wBuff); res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr("close error: %s\n", safe_strerror(-res)); diff --git a/src/sg_write_verify.c b/src/sg_write_verify.c index 00adb6e0..aae62257 100644 --- a/src/sg_write_verify.c +++ b/src/sg_write_verify.c @@ -288,7 +288,8 @@ main(int argc, char * argv[]) uint64_t llba = 0; int64_t ll; uint8_t * wvb = NULL; - void * wrkBuff = NULL; + uint8_t * wrkBuff = NULL; + uint8_t * free_wrkBuff = NULL; const char * device_name = NULL; const char * ifnp; char cmd_name[32]; @@ -497,9 +498,10 @@ main(int argc, char * argv[]) } else if (verbose) pr2serr("Using file size of %d bytes\n", ilen); } - if (NULL == (wrkBuff = malloc(ilen))) { + if (NULL == (wrkBuff = (uint8_t *)sg_memalign(ilen, 0, + &free_wrkBuff, verbose > 3))) { pr2serr(ME "out of memory\n"); - ret = SG_LIB_CAT_OTHER; + ret = sg_convert_errno(ENOMEM); goto err_out; } wvb = (uint8_t *)wrkBuff; @@ -523,9 +525,10 @@ main(int argc, char * argv[]) num_lb, 512, 512 * num_lb); ilen = 512 * num_lb; } - if (NULL == (wrkBuff = malloc(ilen))) { + if (NULL == (wrkBuff = (uint8_t *)sg_memalign(ilen, 0, + &free_wrkBuff, verbose > 3))) { pr2serr(ME "out of memory\n"); - ret = SG_LIB_CAT_OTHER; + ret = sg_convert_errno(ENOMEM); goto err_out; } wvb = (uint8_t *)wrkBuff; @@ -576,8 +579,8 @@ err_out: if (repeat) pr2serr("%d [0x%x] logical blocks written, in total\n", tnum_lb_wr, tnum_lb_wr); - if (wrkBuff) - free(wrkBuff); + if (free_wrkBuff) + free(free_wrkBuff); if ((ifd >= 0) && (STDIN_FILENO != ifd)) close(ifd); res = sg_cmds_close_device(sg_fd); diff --git a/src/sg_write_x.c b/src/sg_write_x.c index 71f4d556..3311ad0d 100644 --- a/src/sg_write_x.c +++ b/src/sg_write_x.c @@ -36,16 +36,16 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.15 20180329"; +static const char * version_str = "1.16 20180425"; /* Protection Information refers to 8 bytes of extra information usually * associated with each logical block and is often abbreviated to PI while * its fields: reference-tag (4 bytes), application-tag (2 bytes) and * tag-mask (2 bytes) are often abbreviated to RT, AT and TM respectively. * And the LBA Range Descriptor associated with the WRITE SCATTERED command - * is abbreviated to RD. A degenerate RD is one where both the LBA and length - * components are zero; they are not illegal according to T10 but are a - * little tricky to handle when scanning and little extra information + * is abbreviated to RD. A degenerate RD is one where length components, + ( and perhaps the LBA, are zero; it is not illegal according to T10 but are + * a little tricky to handle when scanning and little extra information * is provided. */ #define ORWRITE16_OP 0x8b @@ -1841,7 +1841,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == up) { pr2serr("unable to allocate aligned memory for " "scatterlist+data\n"); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return sg_convert_errno(ENOMEM); } ret = bin_read(infd, up, ((if_len < d) ? if_len : d), "IF c1"); if (ret) @@ -1908,7 +1908,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == u2p) { pr2serr("unable to allocate memory for final " "scatterlist+data\n"); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto finii; } memcpy(u2p, up, d); @@ -1943,7 +1943,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == up) { pr2serr("unable to allocate aligned memory for " "scatterlist+data\n"); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return sg_convert_errno(ENOMEM); } num_lbard = 0; sum_num = 0; @@ -2032,7 +2032,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == up) { pr2serr("unable to allocate aligned memory for " "scatterlist+data\n"); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto finii; } ret = bin_read(sfr_fd, up, sf_len, "SF"); @@ -2054,7 +2054,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == u2p) { pr2serr("unable to allocate memory for final " "scatterlist+data\n"); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto finii; } memcpy(u2p, up, dd); @@ -2096,7 +2096,7 @@ process_scattered(int sg_fd, int infd, uint32_t if_len, uint32_t if_rlen, if (NULL == up) { pr2serr("unable to allocate aligned memory for " "scatterlist+data\n"); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto finii; } for (n = lbard_sz, k = 0; k < (int)addr_arr_len; ++k, @@ -2562,7 +2562,7 @@ main(int argc, char * argv[]) up = sg_memalign(do_len, 0, &free_up, false); if (NULL == up) { pr2serr("unable to allocate %u bytes of memory\n", do_len); - ret = SG_LIB_OS_BASE_ERR + ENOMEM; + ret = sg_convert_errno(ENOMEM); goto err_out; } ret = bin_read(infd, up, ((if_len < do_len) ? if_len : do_len), diff --git a/src/sginfo.c b/src/sginfo.c index b466e8f1..6569140a 100644 --- a/src/sginfo.c +++ b/src/sginfo.c @@ -374,7 +374,7 @@ struct scsi_cmnd_io #define SENSE_BUFF_LEN 64 #define CMD_TIMEOUT 60000 /* 60,000 milliseconds (60 seconds) */ -#define EBUFF_SZ 256 +#define EBUFF_SZ 512 #define GENERAL_ERROR 1 diff --git a/src/sgm_dd.c b/src/sgm_dd.c index 0e2f6483..90729f0a 100644 --- a/src/sgm_dd.c +++ b/src/sgm_dd.c @@ -66,7 +66,7 @@ #include "sg_pr2serr.h" -static const char * version_str = "1.51 20171209"; +static const char * version_str = "1.53 20180502"; #define DEF_BLOCK_SIZE 512 #define DEF_BLOCKS_PER_TRANSFER 128 @@ -680,7 +680,7 @@ process_flags(const char * arg, struct flags_t * fp) #define STR_SZ 1024 #define INOUTF_SZ 512 -#define EBUFF_SZ 512 +#define EBUFF_SZ 768 int @@ -1187,24 +1187,18 @@ main(int argc, char * argv[]) if (wrkMmap) { wrkPos = wrkMmap; } else { - if ((FT_RAW == in_type) || (FT_RAW == out_type)) { - wrkBuff = (uint8_t *)malloc(blk_sz * bpt + psz); - if (NULL == wrkBuff) { - pr2serr("Not enough user memory for raw\n"); - return SG_LIB_FILE_ERROR; - } + wrkPos = (uint8_t *)sg_memalign(blk_sz * bpt, 0, &wrkBuff, + verbose > 3); + if (NULL == wrkPos) { + pr2serr("Not enough user memory\n"); + return sg_convert_errno(ENOMEM); + } +#if 0 /* keep copy of hack below, just in case ... */ /* perhaps use posix_memalign() instead */ + wrkBuff = (uint8_t *)malloc(blk_sz * bpt + psz); wrkPos = (uint8_t *)(((sg_uintptr_t)wrkBuff + psz - 1) & (~(psz - 1))); - } - else { - wrkBuff = (uint8_t *)malloc(blk_sz * bpt); - if (NULL == wrkBuff) { - pr2serr("Not enough user memory\n"); - return SG_LIB_FILE_ERROR; - } - wrkPos = wrkBuff; - } +#endif } blocks_per = bpt; diff --git a/src/sgp_dd.c b/src/sgp_dd.c index df5e12f2..de9697ea 100644 --- a/src/sgp_dd.c +++ b/src/sgp_dd.c @@ -60,7 +60,7 @@ #include "sg_pr2serr.h" -static const char * version_str = "5.62 20180219"; +static const char * version_str = "5.63 20180502"; #define DEF_BLOCK_SIZE 512 #define DEF_BLOCKS_PER_TRANSFER 128 @@ -68,7 +68,6 @@ static const char * version_str = "5.62 20180219"; #define DEF_SCSI_CDBSZ 10 #define MAX_SCSI_CDBSZ 16 -#define ME "sgp_dd: " /* #define SG_DEBUG */ @@ -97,7 +96,7 @@ static const char * version_str = "5.62 20180219"; #define DEV_NULL_MINOR_NUM 3 -#define EBUFF_SZ 512 +#define EBUFF_SZ 768 struct flags_t { bool append; @@ -190,6 +189,8 @@ static int64_t dd_count = -1; static int num_threads = DEF_NUM_THREADS; static int exit_status = 0; +static const char * my_name = "sgp_dd: "; + static void calc_duration_throughput(int contin) @@ -482,7 +483,7 @@ sig_listen_thread(void * v_clp) if (shutting_down) break; if (SIGINT == sig_number) { - pr2serr(ME "interrupted by SIGINT\n"); + pr2serr("%sinterrupted by SIGINT\n", my_name); guarded_stop_both(clp); pthread_cond_broadcast(&clp->out_sync_cv); } @@ -740,18 +741,18 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks, sg_put_unaligned_be24(0x1fffff & start_block, cdbp + 1); cdbp[4] = (256 == blocks) ? 0 : (uint8_t)blocks; if (blocks > 256) { - pr2serr(ME "for 6 byte commands, maximum number of blocks is " - "256\n"); + pr2serr("%sfor 6 byte commands, maximum number of blocks is " + "256\n", my_name); return 1; } if ((start_block + blocks - 1) & (~0x1fffff)) { - pr2serr(ME "for 6 byte commands, can't address blocks beyond " - "%d\n", 0x1fffff); + pr2serr("%sfor 6 byte commands, can't address blocks beyond " + "%d\n", my_name, 0x1fffff); return 1; } if (dpo || fua) { - pr2serr(ME "for 6 byte commands, neither dpo nor fua bits " - "supported\n"); + pr2serr("%sfor 6 byte commands, neither dpo nor fua bits " + "supported\n", my_name); return 1; } break; @@ -762,8 +763,8 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks, sg_put_unaligned_be32((uint32_t)start_block, cdbp + 2); sg_put_unaligned_be16((uint16_t)blocks, cdbp + 7); if (blocks & (~0xffff)) { - pr2serr(ME "for 10 byte commands, maximum number of blocks is " - "%d\n", 0xffff); + pr2serr("%sfor 10 byte commands, maximum number of blocks is " + "%d\n", my_name, 0xffff); return 1; } break; @@ -782,8 +783,8 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks, sg_put_unaligned_be32((uint32_t)blocks, cdbp + 10); break; default: - pr2serr(ME "expected cdb size of 6, 10, 12, or 16 but got %d\n", - cdb_sz); + pr2serr("%sexpected cdb size of 6, 10, 12, or 16 but got %d\n", + my_name, cdb_sz); return 1; } return 0; @@ -801,7 +802,8 @@ sg_in_operation(Rq_coll * clp, Rq_elem * rep) if (1 == res) err_exit(ENOMEM, "sg starting in command"); else if (res < 0) { - pr2serr(ME "inputting to sg failed, blk=%" PRId64 "\n", rep->blk); + pr2serr("%sinputting to sg failed, blk=%" PRId64 "\n", my_name, + rep->blk); status = pthread_mutex_unlock(&clp->in_mutex); if (0 != status) err_exit(status, "unlock in_mutex"); guarded_stop_both(clp); @@ -876,8 +878,8 @@ sg_out_operation(Rq_coll * clp, Rq_elem * rep) if (1 == res) err_exit(ENOMEM, "sg starting out command"); else if (res < 0) { - pr2serr(ME "outputting from sg failed, blk=%" PRId64 "\n", - rep->blk); + pr2serr("%soutputting from sg failed, blk=%" PRId64 "\n", + my_name, rep->blk); status = pthread_mutex_unlock(&clp->out_mutex); if (0 != status) err_exit(status, "unlock out_mutex"); guarded_stop_both(clp); @@ -950,8 +952,8 @@ sg_start_io(Rq_elem * rep) if (sg_build_scsi_cdb(rep->cmd, cdbsz, rep->num_blks, rep->blk, rep->wr, fua, dpo)) { - pr2serr(ME "bad cdb build, start_blk=%" PRId64 ", blocks=%d\n", - rep->blk, rep->num_blks); + pr2serr("%sbad cdb build, start_blk=%" PRId64 ", blocks=%d\n", + my_name, rep->blk, rep->num_blks); return -1; } memset(hp, 0, sizeof(struct sg_io_hdr)); @@ -1068,17 +1070,17 @@ sg_prepare(int fd, int bs, int bpt) res = ioctl(fd, SG_GET_VERSION_NUM, &t); if ((res < 0) || (t < 30000)) { - pr2serr(ME "sg driver prior to 3.x.y\n"); + pr2serr("%ssg driver prior to 3.x.y\n", my_name); return 1; } t = bs * bpt; res = ioctl(fd, SG_SET_RESERVED_SIZE, &t); if (res < 0) - perror(ME "SG_SET_RESERVED_SIZE error"); + perror("sgp_dd: SG_SET_RESERVED_SIZE error"); t = 1; res = ioctl(fd, SG_SET_FORCE_PACK_ID, &t); if (res < 0) - perror(ME "SG_SET_FORCE_PACK_ID error"); + perror("sgp_dd: SG_SET_FORCE_PACK_ID error"); return 0; } @@ -1185,14 +1187,14 @@ main(int argc, char * argv[]) if (0 == strcmp(key,"bpt")) { rcoll.bpt = sg_get_num(buf); if (-1 == rcoll.bpt) { - pr2serr(ME "bad argument to 'bpt='\n"); + pr2serr("%sbad argument to 'bpt='\n", my_name); return SG_LIB_SYNTAX_ERROR; } bpt_given = 1; } else if (0 == strcmp(key,"bs")) { rcoll.bs = sg_get_num(buf); if (-1 == rcoll.bs) { - pr2serr(ME "bad argument to 'bs='\n"); + pr2serr("%sbad argument to 'bs='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key,"cdbsz")) { @@ -1206,7 +1208,7 @@ main(int argc, char * argv[]) if (0 != strcmp("-1", buf)) { dd_count = sg_get_llnum(buf); if (-1LL == dd_count) { - pr2serr(ME "bad argument to 'count='\n"); + pr2serr("%sbad argument to 'count='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } /* treat 'count=-1' as calculate count (same as not given) */ @@ -1225,7 +1227,7 @@ main(int argc, char * argv[]) } else if (0 == strcmp(key,"ibs")) { ibs = sg_get_num(buf); if (-1 == ibs) { - pr2serr(ME "bad argument to 'ibs='\n"); + pr2serr("%sbad argument to 'ibs='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (strcmp(key,"if") == 0) { @@ -1236,13 +1238,13 @@ main(int argc, char * argv[]) strncpy(inf, buf, INOUTF_SZ); } else if (0 == strcmp(key, "iflag")) { if (process_flags(buf, &rcoll.in_flags)) { - pr2serr(ME "bad argument to 'iflag='\n"); + pr2serr("%sbad argument to 'iflag='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key,"obs")) { obs = sg_get_num(buf); if (-1 == obs) { - pr2serr(ME "bad argument to 'obs='\n"); + pr2serr("%sbad argument to 'obs='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (strcmp(key,"of") == 0) { @@ -1253,19 +1255,19 @@ main(int argc, char * argv[]) strncpy(outf, buf, INOUTF_SZ); } else if (0 == strcmp(key, "oflag")) { if (process_flags(buf, &rcoll.out_flags)) { - pr2serr(ME "bad argument to 'oflag='\n"); + pr2serr("%sbad argument to 'oflag='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key,"seek")) { seek = sg_get_llnum(buf); if (-1LL == seek) { - pr2serr(ME "bad argument to 'seek='\n"); + pr2serr("%sbad argument to 'seek='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key,"skip")) { skip = sg_get_llnum(buf); if (-1LL == skip) { - pr2serr(ME "bad argument to 'skip='\n"); + pr2serr("%sbad argument to 'skip='\n", my_name); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key,"sync")) @@ -1281,7 +1283,7 @@ main(int argc, char * argv[]) return 0; } else if ((0 == strncmp(key, "--vers", 6)) || (0 == strcmp(key, "-V"))) { - pr2serr(ME ": %s\n", version_str); + pr2serr("%s%s\n", my_name, version_str); return 0; } else { @@ -1322,8 +1324,8 @@ main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } if (rcoll.debug) - pr2serr(ME "if=%s skip=%" PRId64 " of=%s seek=%" PRId64 " count=%" - PRId64 "\n", inf, skip, outf, seek, dd_count); + pr2serr("%sif=%s skip=%" PRId64 " of=%s seek=%" PRId64 " count=%" + PRId64 "\n", my_name, inf, skip, outf, seek, dd_count); install_handler(SIGINT, interrupt_handler); install_handler(SIGQUIT, interrupt_handler); @@ -1336,10 +1338,10 @@ main(int argc, char * argv[]) rcoll.in_type = dd_filetype(inf); if (FT_ERROR == rcoll.in_type) { - pr2serr(ME "unable to access %s\n", inf); + pr2serr("%sunable to access %s\n", my_name, inf); return SG_LIB_FILE_ERROR; } else if (FT_ST == rcoll.in_type) { - pr2serr(ME "unable to use scsi tape device %s\n", inf); + pr2serr("%sunable to use scsi tape device %s\n", my_name, inf); return SG_LIB_FILE_ERROR; } else if (FT_SG == rcoll.in_type) { flags = O_RDWR; @@ -1351,8 +1353,8 @@ main(int argc, char * argv[]) flags |= O_SYNC; if ((rcoll.infd = open(inf, flags)) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "could not open %s for sg reading", inf); + snprintf(ebuff, EBUFF_SZ, "%scould not open %s for sg " + "reading", my_name, inf); perror(ebuff); return SG_LIB_FILE_ERROR; } @@ -1369,8 +1371,8 @@ main(int argc, char * argv[]) flags |= O_SYNC; if ((rcoll.infd = open(inf, flags)) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "could not open %s for reading", inf); + snprintf(ebuff, EBUFF_SZ, "%scould not open %s for reading", + my_name, inf); perror(ebuff); return SG_LIB_FILE_ERROR; } @@ -1379,8 +1381,8 @@ main(int argc, char * argv[]) offset *= rcoll.bs; /* could exceed 32 here! */ if (lseek64(rcoll.infd, offset, SEEK_SET) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "couldn't skip to required position on %s", inf); + snprintf(ebuff, EBUFF_SZ, "%scouldn't skip to required " + "position on %s", my_name, inf); perror(ebuff); return SG_LIB_FILE_ERROR; } @@ -1391,7 +1393,7 @@ main(int argc, char * argv[]) rcoll.out_type = dd_filetype(outf); if (FT_ST == rcoll.out_type) { - pr2serr(ME "unable to use scsi tape device %s\n", outf); + pr2serr("%sunable to use scsi tape device %s\n", my_name, outf); return SG_LIB_FILE_ERROR; } else if (FT_SG == rcoll.out_type) { @@ -1404,8 +1406,8 @@ main(int argc, char * argv[]) flags |= O_SYNC; if ((rcoll.outfd = open(outf, flags)) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "could not open %s for sg writing", outf); + snprintf(ebuff, EBUFF_SZ, "%scould not open %s for sg " + "writing", my_name, outf); perror(ebuff); return SG_LIB_FILE_ERROR; } @@ -1428,16 +1430,16 @@ main(int argc, char * argv[]) flags |= O_APPEND; if ((rcoll.outfd = open(outf, flags, 0666)) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "could not open %s for writing", outf); + snprintf(ebuff, EBUFF_SZ, "%scould not open %s for " + "writing", my_name, outf); perror(ebuff); return SG_LIB_FILE_ERROR; } } else { /* raw output file */ if ((rcoll.outfd = open(outf, O_WRONLY)) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "could not open %s for raw writing", outf); + snprintf(ebuff, EBUFF_SZ, "%scould not open %s for raw " + "writing", my_name, outf); perror(ebuff); return SG_LIB_FILE_ERROR; } @@ -1447,8 +1449,8 @@ main(int argc, char * argv[]) offset *= rcoll.bs; /* could exceed 32 bits here! */ if (lseek64(rcoll.outfd, offset, SEEK_SET) < 0) { - snprintf(ebuff, EBUFF_SZ, - ME "couldn't seek to required position on %s", outf); + snprintf(ebuff, EBUFF_SZ, "%scouldn't seek to required " + "position on %s", my_name, outf); perror(ebuff); return SG_LIB_FILE_ERROR; } |