aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-01-13 16:09:58 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-01-13 16:09:58 +0000
commit070eae9c6711b900abc1a46e09de0bbc515028a2 (patch)
tree4bc5feea6f7e300dc2282197b1ad9d3bec710b41 /testing
parent6a2fe0f14972e955e466a0d36f3a8b1d15dc3fcc (diff)
downloadsg3_utils-070eae9c6711b900abc1a46e09de0bbc515028a2.tar.gz
testing update for hipri; testing/uapi_sg.h update
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@873 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/sg_mrq_dd.cpp67
-rw-r--r--testing/sgh_dd.cpp30
-rw-r--r--testing/uapi_sg.h29
3 files changed, 99 insertions, 27 deletions
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 27424a02..8496617e 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -2,7 +2,7 @@
* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 2018-2020 D. Gilbert
+ * Copyright (C) 2018-2021 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.16 20201105";
+static const char * version_str = "1.17 20210106";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -178,6 +178,7 @@ struct flags_t {
bool excl;
bool ff;
bool fua;
+ bool hipri;
bool masync; /* more async sg v4 driver fd flag */
bool no_dur;
bool nocreat;
@@ -537,16 +538,26 @@ sg_flags_str(int flags, int b_len, char * b)
if (n >= b_len)
goto fini;
}
- if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */
+ if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */
n += sg_scnpr(b + n, b_len - n, "EVFD|");
if (n >= b_len)
goto fini;
}
- if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */
+ if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */
n += sg_scnpr(b + n, b_len - n, "OWR|");
if (n >= b_len)
goto fini;
}
+ if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */
+ n += sg_scnpr(b + n, b_len - n, "RECO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SGV4_FLAG_HIPRI & flags) { /* 0x200000 */
+ n += sg_scnpr(b + n, b_len - n, "HIPRI|");
+ if (n >= b_len)
+ goto fini;
+ }
fini:
if (n < b_len) { /* trim trailing '\' */
if ('|' == b[n - 1])
@@ -929,6 +940,8 @@ page3:
"iflags)\n"
" fua sets the FUA (force unit access) in SCSI READs "
"and WRITEs\n"
+ " hipri set HIPRI flag and use blk_poll() for "
+ "completions\n"
" masync set 'more async' flag on this sg device\n"
" mmap setup mmap IO on IFILE or OFILE\n"
" mmap,mmap when used twice, doesn't call munmap()\n"
@@ -1814,6 +1827,8 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
rflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
rflags |= SGV4_FLAG_NO_WAITQ;
+ if (flagsp->hipri)
+ rflags |= SGV4_FLAG_HIPRI;
for (k = 0, num = 0; seg_blks > 0; ++k, seg_blks -= num) {
kk = min<int>(seg_blks, clp->bpt);
@@ -1930,6 +1945,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
rflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
rflags |= SGV4_FLAG_NO_WAITQ;
+ if (flagsp->hipri)
+ rflags |= SGV4_FLAG_HIPRI;
for (k = 0, num = 0; seg_blks > 0; ++k, seg_blks -= num) {
kk = min<int>(seg_blks, clp->bpt);
@@ -1992,6 +2009,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS;
if (! flagsp->coe)
ctl_v4.flags |= SGV4_FLAG_STOP_IF;
+ if (flagsp->hipri)
+ rflags |= SGV4_FLAG_HIPRI;
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */
@@ -2324,6 +2343,8 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
iflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
iflags |= SGV4_FLAG_NO_WAITQ;
+ if (iflagsp->hipri)
+ iflags |= SGV4_FLAG_HIPRI;
oflags = SGV4_FLAG_SHARE | SGV4_FLAG_NO_DXFER;
if (oflagsp->dio)
@@ -2334,6 +2355,8 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
oflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
oflags |= SGV4_FLAG_NO_WAITQ;
+ if (oflagsp->hipri)
+ oflags |= SGV4_FLAG_HIPRI;
for (k = 0; seg_blks > 0; ++k, seg_blks -= num) {
kk = min<int>(seg_blks, clp->bpt);
@@ -2501,6 +2524,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
iflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
iflags |= SGV4_FLAG_NO_WAITQ;
+ if (iflagsp->hipri)
+ iflags |= SGV4_FLAG_HIPRI;
oflags = SGV4_FLAG_SHARE | SGV4_FLAG_NO_DXFER;
if (oflagsp->dio)
@@ -2511,6 +2536,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
oflags |= SGV4_FLAG_Q_AT_TAIL;
if (clp->no_waitq)
oflags |= SGV4_FLAG_NO_WAITQ;
+ if (oflagsp->hipri)
+ oflags |= SGV4_FLAG_HIPRI;
oflags |= SGV4_FLAG_DO_ON_OTHER;
for (k = 0; seg_blks > 0; ++k, seg_blks -= num) {
@@ -2603,6 +2630,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
ctl_v4.flags |= SGV4_FLAG_STOP_IF;
if ((! clp->verify) && clp->out_flags.order)
ctl_v4.flags |= SGV4_FLAG_ORDERED_WR;
+ if (! (iflagsp->hipri || oflagsp->hipri))
+ ctl_v4.flags |= SGV4_FLAG_HIPRI;
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */
@@ -2692,6 +2721,31 @@ fini:
return res < 0 ? res : (min<int>(in_fin_blks, out_fin_blks));
}
+/* Returns number found and (partially) processed. 'num' is the number of
+ * completions to wait for when > 0. When 'num' is zero check all inflight
+ * request on 'fd' and return quickly if none completed (i.e. don't wait)
+ * If error return negative errno and if no request inflight or waiting
+ * then return -9999 . */
+static int
+sg_blk_poll(int fd, int num)
+{
+ int res;
+ struct sg_extended_info sei;
+ struct sg_extended_info * seip = &sei;
+
+ memset(seip, 0, sizeof(*seip));
+ seip->sei_rd_mask |= SG_SEIM_BLK_POLL;
+ seip->sei_wr_mask |= SG_SEIM_BLK_POLL;
+ seip->num = (num < 0) ? 0 : num;
+ res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
+ if (res < 0) {
+ pr2serr_lk("%s: SG_SET_GET_EXTENDED(BLK_POLL) error: %s\n",
+ __func__, strerror(errno));
+ return res;
+ }
+ return (seip->num == -1) ? -9999 : seip->num;
+}
+
/* Returns reserved_buffer_size/mmap_size if success, else 0 for failure */
static int
sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
@@ -2705,9 +2759,8 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
int res, t, num, err;
uint8_t *mmp;
struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
if ((res < 0) || (t < 40000)) {
if (ioctl(fd, SG_GET_RESERVED_SIZE, &num) < 0) {
@@ -2944,6 +2997,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->ff = true;
else if (0 == strcmp(cp, "fua"))
fp->fua = true;
+ else if (0 == strcmp(cp, "hipri"))
+ fp->hipri = true;
else if (0 == strcmp(cp, "masync"))
fp->masync = true;
else if (0 == strcmp(cp, "mmap"))
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index d0b8ab29..f0b145f8 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -2,7 +2,7 @@
* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 2018-2020 D. Gilbert
+ * Copyright (C) 2018-2021 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.97 20201124";
+static const char * version_str = "1.98 20210106";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -173,6 +173,7 @@ struct flags_t {
bool excl;
bool ff;
bool fua;
+ bool hipri;
bool masync; /* more async sg v4 driver flag */
bool mrq_immed; /* mrq submit non-blocking */
bool mrq_svb; /* mrq shared_variable_block, for sg->sg copy */
@@ -589,16 +590,26 @@ sg_flags_str(int flags, int b_len, char * b)
if (n >= b_len)
goto fini;
}
- if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */
+ if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */
n += sg_scnpr(b + n, b_len - n, "EVFD|");
if (n >= b_len)
goto fini;
}
- if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */
+ if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */
n += sg_scnpr(b + n, b_len - n, "OWR|");
if (n >= b_len)
goto fini;
}
+ if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */
+ n += sg_scnpr(b + n, b_len - n, "RECO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SGV4_FLAG_HIPRI & flags) { /* 0x200000 */
+ n += sg_scnpr(b + n, b_len - n, "HIPRI|");
+ if (n >= b_len)
+ goto fini;
+ }
if (0 == n)
n += sg_scnpr(b + n, b_len - n, "<none>");
fini:
@@ -891,10 +902,10 @@ usage(int pg_num)
goto page2;
pr2serr("Usage: sgh_dd [bs=BS] [conv=CONVS] [count=COUNT] [ibs=BS] "
- "[if=IFILE]\n"
+ "[if=IFILE]\n"
" [iflag=FLAGS] [obs=BS] [of=OFILE] [oflag=FLAGS] "
"[seek=SEEK]\n"
- " [skip=SKIP] [--help] [--version]\n\n");
+ " [skip=SKIP] [--help] [--version]\n\n");
pr2serr(" [ae=AEN[,MAEN]] [bpt=BPT] [cdbsz=6|10|12|16] "
"[coe=0|1]\n"
" [dio=0|1] [elemsz_kb=EKB] [fail_mask=FM] "
@@ -1016,6 +1027,8 @@ page3:
"iflags)\n"
" fua sets the FUA (force unit access) in SCSI READs "
"and WRITEs\n"
+ " hipri set HIPRI flag on command, uses blk_poll() to "
+ "complete\n"
" masync set 'more async' flag on this sg device\n"
" mmap setup mmap IO on IFILE or OFILE; OFILE only "
"with noshare\n"
@@ -3001,6 +3014,7 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
bool v4 = wr ? clp->out_flags.v4 : clp->in_flags.v4;
bool qhead = wr ? clp->out_flags.qhead : clp->in_flags.qhead;
bool qtail = wr ? clp->out_flags.qtail : clp->in_flags.qtail;
+ bool hipri = wr ? clp->out_flags.hipri : clp->in_flags.hipri;
bool prefetch = xtrp ? xtrp->prefetch : false;
bool is_wr2 = xtrp ? xtrp->is_wr2 : false;
int cdbsz = wr ? clp->cdbsz_out : clp->cdbsz_in;
@@ -3059,6 +3073,8 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
flags |= SG_FLAG_NO_DXFER;
if (dio)
flags |= SG_FLAG_DIRECT_IO;
+ if (hipri)
+ flags |= SGV4_FLAG_HIPRI;
if (qhead)
flags |= SG_FLAG_Q_AT_HEAD;
if (qtail)
@@ -3651,6 +3667,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->ff = true;
else if (0 == strcmp(cp, "fua"))
fp->fua = true;
+ else if (0 == strcmp(cp, "hipri"))
+ fp->hipri = true;
else if (0 == strcmp(cp, "masync"))
fp->masync = true;
else if (0 == strcmp(cp, "mmap"))
diff --git a/testing/uapi_sg.h b/testing/uapi_sg.h
index aa20c219..0cdbc249 100644
--- a/testing/uapi_sg.h
+++ b/testing/uapi_sg.h
@@ -14,7 +14,7 @@
* Later extensions (versions 2, 3 and 4) to driver:
* Copyright (C) 1998 - 2021 Douglas Gilbert
*
- * Version 4.0.46 (20210101)
+ * Version 4.0.46 (20210111)
* This version is for Linux 4 and 5 series kernels.
*
* Documentation
@@ -119,17 +119,17 @@ typedef struct sg_io_hdr {
#define SGV4_FLAG_COMPLETE_B4 0x100 /* mrq: complete this rq before next */
#define SGV4_FLAG_SIGNAL 0x200 /* v3: ignored; v4 signal on completion */
#define SGV4_FLAG_IMMED 0x400 /* issue request and return immediately ... */
-#define SGV4_FLAG_STOP_IF 0x800 /* Stops sync mrq if error or warning */
-#define SGV4_FLAG_DEV_SCOPE 0x1000 /* permit SG_IOABORT to have wider scope */
-#define SGV4_FLAG_SHARE 0x2000 /* share IO buffer; needs SG_SEIM_SHARE_FD */
-#define SGV4_FLAG_DO_ON_OTHER 0x4000 /* available on either of shared pair */
-#define SGV4_FLAG_KEEP_SHARE 0x8000 /* ... buffer for another dout command */
+#define SGV4_FLAG_HIPRI 0x800 /* request will use blk_poll to complete */
+#define SGV4_FLAG_STOP_IF 0x1000 /* Stops sync mrq if error or warning */
+#define SGV4_FLAG_DEV_SCOPE 0x2000 /* permit SG_IOABORT to have wider scope */
+#define SGV4_FLAG_SHARE 0x4000 /* share IO buffer; needs SG_SEIM_SHARE_FD */
+#define SGV4_FLAG_DO_ON_OTHER 0x8000 /* available on either of shared pair */
#define SGV4_FLAG_NO_DXFER SG_FLAG_NO_DXFER /* needed for sharing */
-#define SGV4_FLAG_MULTIPLE_REQS 0x20000 /* 1 or more sg_io_v4-s in data-in */
-#define SGV4_FLAG_EVENTFD 0x40000 /* signal completion on ... */
-#define SGV4_FLAG_ORDERED_WR 0x80000 /* svb: issue in-order writes */
-#define SGV4_FLAG_REC_ORDER 0x100000 /* receive order in v4:request_priority */
-#define SGV4_FLAG_HIPRI 0x200000 /* completion via SG_SEIM_BLK_POLL */
+#define SGV4_FLAG_KEEP_SHARE 0x20000 /* ... buffer for another dout command */
+#define SGV4_FLAG_MULTIPLE_REQS 0x40000 /* 1 or more sg_io_v4-s in data-in */
+#define SGV4_FLAG_EVENTFD 0x80000 /* signal completion on ... */
+#define SGV4_FLAG_ORDERED_WR 0x100000 /* svb: issue in-order writes */
+#define SGV4_FLAG_REC_ORDER 0x200000 /* receive order in v4:request_priority */
/* Output (potentially OR-ed together) in v3::info or v4::info field */
#define SG_INFO_OK_MASK 0x1
@@ -199,8 +199,8 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
#define SG_SEIM_SHARE_FD 0x20 /* write-side gives fd of read-side */
#define SG_SEIM_CHG_SHARE_FD 0x40 /* read-side given new write-side fd */
#define SG_SEIM_SGAT_ELEM_SZ 0x80 /* sgat element size (>= PAGE_SIZE) */
-#define SG_SEIM_EVENTFD 0x100 /* pass eventfd to driver */
-#define SG_SEIM_BLK_POLL 0x200 /* call blk_poll, uses general field */
+#define SG_SEIM_BLK_POLL 0x100 /* call blk_poll, uses 'num' field */
+#define SG_SEIM_EVENTFD 0x200 /* pass eventfd to driver */
#define SG_SEIM_ALL_BITS 0x3ff /* should be OR of previous items */
/* flag and mask values for boolean fields follow */
@@ -262,8 +262,7 @@ struct sg_extended_info {
__u32 minor_index; /* rd: kernel's sg device minor number */
__u32 share_fd; /* for SHARE_FD, CHG_SHARE_FD or EVENTFD */
__u32 sgat_elem_sz; /* sgat element size (must be power of 2) */
- __s32 num; /* blk_poll: spin for num (0: no spin); raw */
- /* read number completed */
+ __s32 num; /* blk_poll: loop_count (-1 -> spin)) */
__u8 pad_to_96[48]; /* pad so struct is 96 bytes long */
};