diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2019-01-23 16:25:58 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2019-01-23 16:25:58 +0000 |
commit | a918d1a30569c4d3f09cc87836ff19215db6d8b7 (patch) | |
tree | 9d75cdc5dc54583fd103800abbd732e4d1fe5023 /src | |
parent | e168d3764b642fd96aac1c65f83a64af994ee111 (diff) | |
download | sg3_utils-a918d1a30569c4d3f09cc87836ff19215db6d8b7.tar.gz |
sg_xcopy: add --fco (fast copy only) (spc5r20), implement --app=1 (append) on regular OFILE type; sg_tst_bidi work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@808 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/sg_vpd.c | 88 | ||||
-rw-r--r-- | src/sg_xcopy.c | 17 |
2 files changed, 74 insertions, 31 deletions
diff --git a/src/sg_vpd.c b/src/sg_vpd.c index 04d5110d..ed55d90f 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -40,7 +40,7 @@ */ -static const char * version_str = "1.49 20190109"; /* spc5r20 + sbc4r15 */ +static const char * version_str = "1.50 20190119"; /* spc5r20 + sbc4r15 */ /* standard VPD pages, in ascending page number order */ #define VPD_SUPPORTED_VPDS 0x0 @@ -152,9 +152,10 @@ static int svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, static int svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue, int off); -static int decode_dev_ids(const char * print_if_found, uint8_t * buff, - int len, int m_assoc, int m_desig_type, - int m_code_set, const struct opts_t * op); +static int decode_dev_ids(const char * print_if_found, int num_leading, + uint8_t * buff, int len, int m_assoc, + int m_desig_type, int m_code_set, + const struct opts_t * op); uint8_t * rsp_buff; const int rsp_buff_sz = MX_ALLOC_LEN + 2; @@ -746,23 +747,23 @@ decode_id_vpd(uint8_t * buff, int len, int subvalue, m_d = -1; m_cs = -1; if (0 == subvalue) { - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), b, blen, + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), 0, b, blen, VPD_ASSOC_LU, m_d, m_cs, op); - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), b, blen, + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), 0, b, blen, VPD_ASSOC_TPORT, m_d, m_cs, op); - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), b, blen, + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), 0, b, blen, VPD_ASSOC_TDEVICE, m_d, m_cs, op); } else if (VPD_DI_SEL_AS_IS == subvalue) - decode_dev_ids(NULL, b, blen, m_a, m_d, m_cs, op); + decode_dev_ids(NULL, 0, b, blen, m_a, m_d, m_cs, op); else { if (VPD_DI_SEL_LU & subvalue) - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), b, blen, + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), 0, b, blen, VPD_ASSOC_LU, m_d, m_cs, op); if (VPD_DI_SEL_TPORT & subvalue) - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), b, blen, - VPD_ASSOC_TPORT, m_d, m_cs, op); + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), 0, b, + blen, VPD_ASSOC_TPORT, m_d, m_cs, op); if (VPD_DI_SEL_TARGET & subvalue) - decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), + decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), 0, b, blen, VPD_ASSOC_TDEVICE, m_d, m_cs, op); } } @@ -925,8 +926,8 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, const struct opts_t * op) } else { if ((0 == op->do_quiet) || (ip_tid_len > 0)) printf(" Target port descriptor(s):\n"); - decode_dev_ids("SCSI Ports", bp + bump + 4, tpd_len, - VPD_ASSOC_TPORT, -1, -1, op); + decode_dev_ids("", 2 /* leading spaces */, bp + bump + 4, + tpd_len, VPD_ASSOC_TPORT, -1, -1, op); } } bump += tpd_len + 4; @@ -1133,18 +1134,25 @@ decode_dev_ids_quiet(uint8_t * buff, int len, int m_assoc, /* Prints outs designation descriptors (dd_s)selected by association, designator type and/or code set. */ static int -decode_dev_ids(const char * print_if_found, uint8_t * buff, int len, - int m_assoc, int m_desig_type, int m_code_set, +decode_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff, + int len, int m_assoc, int m_desig_type, int m_code_set, const struct opts_t * op) { int assoc, off, u, i_len; bool printed; const uint8_t * bp; char b[1024]; + char sp[82]; if (op->do_quiet) return decode_dev_ids_quiet(buff, len, m_assoc, m_desig_type, m_code_set); + if (num_leading > (int)(sizeof(sp) - 2)) + num_leading = sizeof(sp) - 2; + if (num_leading > 0) + snprintf(sp, sizeof(sp), "%*c", num_leading, ' '); + else + sp[0] = '\0'; if (buff[2] != 0) { /* all valid dd_s should have 0 in this byte */ if (op->verbose) pr2serr("%s: designation descriptors byte 2 should be 0\n" @@ -1166,11 +1174,12 @@ decode_dev_ids(const char * print_if_found, uint8_t * buff, int len, assoc = ((bp[1] >> 4) & 0x3); if (print_if_found && (! printed)) { printed = true; - printf(" %s:\n", print_if_found); + if (strlen(print_if_found) > 0) + printf(" %s:\n", print_if_found); } if (NULL == print_if_found) - printf(" %s:\n", sg_get_desig_assoc_str(assoc)); - sg_get_designation_descriptor_str("", bp, i_len + 4, false, + printf(" %s%s:\n", sp, sg_get_desig_assoc_str(assoc)); + sg_get_designation_descriptor_str(sp, bp, i_len + 4, false, op->do_long, sizeof(b), b); printf("%s", b); } @@ -1603,6 +1612,7 @@ decode_rod_descriptor(const uint8_t * buff, int len) { const uint8_t * bp = buff; int k, bump; + uint64_t ul; for (k = 0; k < len; k += bump, bp += bump) { bump = sg_get_unaligned_be16(bp + 2) + 4; @@ -1613,26 +1623,46 @@ decode_rod_descriptor(const uint8_t * buff, int len) sg_get_unaligned_be16(bp + 6)); printf(" Maximum Bytes in block ROD: %" PRIu64 "\n", sg_get_unaligned_be64(bp + 8)); - printf(" Optimal Bytes in block ROD transfer: %" PRIu64 "\n", - sg_get_unaligned_be64(bp + 16)); - printf(" Optimal Bytes to token per segment: %" PRIu64 "\n", - sg_get_unaligned_be64(bp + 24)); - printf(" Optimal Bytes from token per segment:" - " %" PRIu64 "\n", sg_get_unaligned_be64(bp + 32)); + ul = sg_get_unaligned_be64(bp + 16); + printf(" Optimal Bytes in block ROD transfer: "); + if (SG_LIB_UNBOUNDED_64BIT == ul) + printf("-1 [no limit]\n"); + else + printf("%" PRIu64 "\n", ul); + ul = sg_get_unaligned_be64(bp + 24); + printf(" Optimal Bytes to token per segment: "); + if (SG_LIB_UNBOUNDED_64BIT == ul) + printf("-1 [no limit]\n"); + else + printf("%" PRIu64 "\n", ul); + ul = sg_get_unaligned_be64(bp + 32); + printf(" Optimal Bytes from token per segment: "); + if (SG_LIB_UNBOUNDED_64BIT == ul) + printf("-1 [no limit]\n"); + else + printf("%" PRIu64 "\n", ul); break; case 1: /* Stream ROD device type specific descriptor */ printf(" Maximum Bytes in stream ROD: %" PRIu64 "\n", sg_get_unaligned_be64(bp + 8)); - printf(" Optimal Bytes in stream ROD transfer:" - " %" PRIu64 "\n", sg_get_unaligned_be64(bp + 16)); + ul = sg_get_unaligned_be64(bp + 16); + printf(" Optimal Bytes in stream ROD transfer: "); + if (SG_LIB_UNBOUNDED_64BIT == ul) + printf("-1 [no limit]\n"); + else + printf("%" PRIu64 "\n", ul); break; case 3: /* Copy manager ROD device type specific descriptor */ printf(" Maximum Bytes in processor ROD: %" PRIu64 "\n", sg_get_unaligned_be64(bp + 8)); - printf(" Optimal Bytes in processor ROD transfer:" - " %" PRIu64 "\n", sg_get_unaligned_be64(bp + 16)); + ul = sg_get_unaligned_be64(bp + 16); + printf(" Optimal Bytes in processor ROD transfer: "); + if (SG_LIB_UNBOUNDED_64BIT == ul) + printf("-1 [no limit]\n"); + else + printf("%" PRIu64 "\n", ul); break; default: printf(" Unhandled descriptor (format %d, device type %d)\n", diff --git a/src/sg_xcopy.c b/src/sg_xcopy.c index 6bfd1dba..c0b53a88 100644 --- a/src/sg_xcopy.c +++ b/src/sg_xcopy.c @@ -1,7 +1,7 @@ /* A utility program for copying files. Similar to 'dd' but using * the 'Extended Copy' command. * - * Copyright (c) 2011-2018 Hannes Reinecke, SUSE Labs + * Copyright (c) 2011-2019 Hannes Reinecke, SUSE Labs * * Largely taken from 'sg_dd', which has the * @@ -69,7 +69,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "0.68 20180811"; +static const char * version_str = "0.69 20190120"; #define ME "sg_xcopy: " @@ -172,6 +172,7 @@ static bool do_time = false; static bool start_tm_valid = false; static bool xcopy_flag_cat = false; static bool xcopy_flag_dc = false; +static bool xcopy_flag_fco = false; /* fast copy only, spc5r20 */ static int blk_sz = 0; static int list_id_usage = -1; static int priority = 1; @@ -533,6 +534,7 @@ primary_help: " conv ignored\n" " count number of blocks to copy (def: device size)\n" " dc xcopy segment descriptor DC bit (default: 0)\n" + " fco xcopy segment descriptor FCO bit (default: 0)\n" " ibs input block size (if given must be same as " "'bs=')\n" " id_usage sets list_id_usage field to hold (0), " @@ -596,6 +598,8 @@ scsi_encode_seg_desc(uint8_t *seg_desc, int seg_desc_type, seg_desc[1] |= 0x1; if (xcopy_flag_dc) seg_desc[1] |= 0x2; + if (xcopy_flag_fco) + seg_desc[1] |= 0x4; if (seg_desc_type == 0x02) { seg_desc_len = 0x18; seg_desc[4] = 0; @@ -1260,6 +1264,8 @@ open_of(struct xcopy_fp_t * ofp, int vb) flags = O_RDWR | O_NONBLOCK; if (ofp->excl) flags |= O_EXCL; + if (ofp->append) + flags |= O_APPEND; if ((outfd = open(ofp->fname, flags)) < 0) { err = errno; snprintf(ebuff, EBUFF_SZ, @@ -1409,6 +1415,13 @@ main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } xcopy_flag_dc = !! n; + } else if (0 == strcmp(key, "fco")) { + n = sg_get_num(buf); + if (n < 0 || n > 1) { + pr2serr(ME "bad argument to 'fco='\n"); + return SG_LIB_SYNTAX_ERROR; + } + xcopy_flag_fco = !! n; } else if (0 == strcmp(key, "ibs")) { ibs = sg_get_num(buf); } else if (strcmp(key, "if") == 0) { |