aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2010-03-26 22:49:04 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2010-03-26 22:49:04 +0000
commitc74ed01de6f00ecd6f1905c9ec6674e25207f5fb (patch)
treed27aafa39533377f1a9c62c6aea8ed054ea91949 /examples
parenta45a0a2dc1b5e2b81034284a6ad485367151831b (diff)
downloadsg3_utils-c74ed01de6f00ecd6f1905c9ec6674e25207f5fb.tar.gz
add examples bsg_queue_tst, wire Q_AT_HEAD flag
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@332 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile10
-rw-r--r--examples/bsg_queue_tst.c171
-rw-r--r--examples/sg_queue_tst.c23
3 files changed, 196 insertions, 8 deletions
diff --git a/examples/Makefile b/examples/Makefile
index 98aa1cce..54ce549a 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -14,6 +14,8 @@ EXECS = sg_simple1 sg_simple2 sg_simple3 sg_simple4 sg_simple16 \
EXTRAS = sg_simple_aio sg_queue_tst
+BSG_EXTRAS = bsg_queue_tst
+
MAN_PGS =
MAN_PREF = man8
@@ -33,12 +35,15 @@ all: $(EXECS)
extras: $(EXTRAS)
+bsg: $(BSG_EXTRAS)
+
+
depend dep:
for i in *.c; do $(CC) $(INCLUDES) $(CFLAGS) -M $$i; \
done > .depend
clean:
- /bin/rm -f *.o $(EXECS) $(EXTRAS) core .depend
+ /bin/rm -f *.o $(EXECS) $(EXTRAS) $(BSG_EXTRAS) core .depend
sg_simple1: sg_simple1.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
@@ -94,6 +99,9 @@ sg_sat_smart_rd_data: sg_sat_smart_rd_data.o $(LIBFILESOLD)
sg_queue_tst: sg_queue_tst.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
+bsg_queue_tst: bsg_queue_tst.o $(LIBFILESOLD)
+ $(LD) -o $@ $(LDFLAGS) $^
+
install: $(EXECS)
install -d $(INSTDIR)
for name in $^; \
diff --git a/examples/bsg_queue_tst.c b/examples/bsg_queue_tst.c
new file mode 100644
index 00000000..998c4958
--- /dev/null
+++ b/examples/bsg_queue_tst.c
@@ -0,0 +1,171 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* If the following fails the Linux kernel is probably too old */
+#include <linux/bsg.h>
+
+
+#include "sg_lib.h"
+#include "sg_io_linux.h"
+#include "sg_linux_inc.h"
+
+/* This program was used to test SCSI mid level queue ordering.
+ The default behaviour is to "queue at head" which is useful for
+ error processing but not for streaming READ and WRITE commands.
+
+* Copyright (C) 2010 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)
+* any later version.
+
+ Invocation: bsg_queue_tst [-t] <bsg_device>
+ -t queue at tail
+
+ Version 0.90 (20100324)
+
+*/
+
+#define INQ_REPLY_LEN 96
+#define INQ_CMD_LEN 6
+#define SDIAG_CMD_LEN 6
+#define SENSE_BUFFER_LEN 96
+
+#define EBUFF_SZ 256
+
+#ifndef BSG_FLAG_Q_AT_TAIL
+#define BSG_FLAG_Q_AT_TAIL 0x10
+#endif
+
+#ifndef BSG_FLAG_Q_AT_HEAD
+#define BSG_FLAG_Q_AT_HEAD 0x20
+#endif
+
+
+int main(int argc, char * argv[])
+{
+ int bsg_fd, k, ok;
+ unsigned char inqCmdBlk[INQ_CMD_LEN] =
+ {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
+ unsigned char sdiagCmdBlk[SDIAG_CMD_LEN] =
+ {0x1d, 0, 0, 0, 0, 0};
+ unsigned char inqBuff[16][INQ_REPLY_LEN];
+ struct sg_io_v4 io_hdr[16];
+ struct sg_io_v4 rio_hdr;
+ char * file_name = 0;
+ char ebuff[EBUFF_SZ];
+ unsigned char sense_buffer[16][SENSE_BUFFER_LEN];
+ int q_at_tail = 0;
+
+ for (k = 1; k < argc; ++k) {
+ if (0 == memcmp("-t", argv[k], 2))
+ ++q_at_tail;
+ else if (*argv[k] == '-') {
+ printf("Unrecognized switch: %s\n", argv[k]);
+ file_name = 0;
+ break;
+ }
+ else if (0 == file_name)
+ file_name = argv[k];
+ else {
+ printf("too many arguments\n");
+ file_name = 0;
+ break;
+ }
+ }
+ if (0 == file_name) {
+ printf("Usage: 'bsg_queue_tst [-t] <bsg_device>'\n"
+ "where:\n -t queue_at_tail (def: q_at_head)\n");
+ return 1;
+ }
+
+ /* An access mode of O_RDWR is required for write()/read() interface */
+ if ((bsg_fd = open(file_name, O_RDWR)) < 0) {
+ snprintf(ebuff, EBUFF_SZ,
+ "bsg_queue_tst: error opening file: %s", file_name);
+ perror(ebuff);
+ return 1;
+ }
+
+ for (k = 0; k < 16; ++k) {
+ /* Prepare INQUIRY command */
+ memset(&io_hdr[k], 0, sizeof(struct sg_io_v4));
+ io_hdr[k].guard = 'Q';
+ /* io_hdr[k].iovec_count = 0; */ /* memset takes care of this */
+ if (0 == (k % 3)) {
+ io_hdr[k].request_len = sizeof(sdiagCmdBlk);
+ io_hdr[k].request = (uint64_t)(long)sdiagCmdBlk;
+ } else {
+ io_hdr[k].request_len = sizeof(inqCmdBlk);
+ io_hdr[k].request = (uint64_t)(long)inqCmdBlk;
+ io_hdr[k].din_xfer_len = INQ_REPLY_LEN;
+ io_hdr[k].din_xferp = (uint64_t)(long)inqBuff[k];
+ }
+ io_hdr[k].response = (uint64_t)(long)sense_buffer[k];
+ io_hdr[k].max_response_len = SENSE_BUFFER_LEN;
+ io_hdr[k].timeout = 20000; /* 20000 millisecs == 20 seconds */
+ io_hdr[k].usr_ptr = k;
+ /* default is to queue at head (in SCSI mid level) */
+ if (q_at_tail)
+ io_hdr[k].flags |= BSG_FLAG_Q_AT_TAIL;
+ else
+ io_hdr[k].flags |= BSG_FLAG_Q_AT_HEAD;
+
+ if (write(bsg_fd, &io_hdr[k], sizeof(struct sg_io_v4)) < 0) {
+ perror("bsg_queue_tst: bsg write error");
+ close(bsg_fd);
+ return 1;
+ }
+ }
+ /* sleep(3); */
+ for (k = 0; k < 16; ++k) {
+ memset(&rio_hdr, 0, sizeof(struct sg_io_v4));
+ rio_hdr.guard = 'Q';
+ if (read(bsg_fd, &rio_hdr, sizeof(struct sg_io_v4)) < 0) {
+ perror("bsg_queue_tst: bsg read error");
+ close(bsg_fd);
+ return 1;
+ }
+ /* now for the error processing */
+ ok = 0;
+ if (0 == rio_hdr.device_status)
+ ok = 1;
+ else {
+ switch (sg_err_category_sense((unsigned char *)(long)rio_hdr.response,
+ rio_hdr.response_len)) {
+ case SG_LIB_CAT_CLEAN:
+ ok = 1;
+ break;
+ case SG_LIB_CAT_RECOVERED:
+ printf("Recovered error, continuing\n");
+ ok = 1;
+ break;
+ default: /* won't bother decoding other categories */
+ sg_print_sense("command error",
+ (unsigned char *)(long)rio_hdr.response,
+ rio_hdr.response_len, 1);
+ break;
+ }
+ }
+
+ if (ok) { /* output result if it is available */
+ /* if (0 == rio_hdr.pack_id) */
+ if (0 == (rio_hdr.usr_ptr % 3))
+ printf("SEND DIAGNOSTIC %d duration=%u\n", (int)rio_hdr.usr_ptr,
+ rio_hdr.duration);
+ else
+ printf("INQUIRY %d duration=%u\n", (int)rio_hdr.usr_ptr,
+ rio_hdr.duration);
+ }
+ }
+
+ close(bsg_fd);
+ return 0;
+}
diff --git a/examples/sg_queue_tst.c b/examples/sg_queue_tst.c
index d7739c44..b8bc549e 100644
--- a/examples/sg_queue_tst.c
+++ b/examples/sg_queue_tst.c
@@ -26,13 +26,14 @@
Invocation: sg_queue_tst [-t] <sg_device>
-t queue at tail
- Version 0.90 (20100320)
+ Version 0.90 (20100324)
*/
#define INQ_REPLY_LEN 96
#define INQ_CMD_LEN 6
#define SDIAG_CMD_LEN 6
+#define SENSE_BUFFER_LEN 96
#define EBUFF_SZ 256
@@ -40,6 +41,10 @@
#define SG_FLAG_Q_AT_TAIL 0x10
#endif
+#ifndef SG_FLAG_Q_AT_HEAD
+#define SG_FLAG_Q_AT_HEAD 0x20
+#endif
+
int main(int argc, char * argv[])
{
@@ -53,7 +58,7 @@ int main(int argc, char * argv[])
sg_io_hdr_t rio_hdr;
char * file_name = 0;
char ebuff[EBUFF_SZ];
- unsigned char sense_buffer[16][32];
+ unsigned char sense_buffer[16][SENSE_BUFFER_LEN];
int q_at_tail = 0;
for (k = 1; k < argc; ++k) {
@@ -73,7 +78,8 @@ int main(int argc, char * argv[])
}
}
if (0 == file_name) {
- printf("Usage: 'sg_queue_tst [-t] <sg_device>'\n");
+ printf("Usage: 'sg_queue_tst [-t] <sg_device>'\n"
+ "where:\n -t queue_at_tail (def: q_at_head)\n");
return 1;
}
@@ -103,15 +109,18 @@ int main(int argc, char * argv[])
io_hdr[k].dxferp = inqBuff[k];
}
io_hdr[k].sbp = sense_buffer[k];
+ io_hdr[k].mx_sb_len = SENSE_BUFFER_LEN;
io_hdr[k].timeout = 20000; /* 20000 millisecs == 20 seconds */
io_hdr[k].pack_id = k;
/* default is to queue at head (in SCSI mid level) */
if (q_at_tail)
io_hdr[k].flags |= SG_FLAG_Q_AT_TAIL;
+ else
+ io_hdr[k].flags |= SG_FLAG_Q_AT_HEAD;
/* io_hdr[k].usr_ptr = NULL; */
if (write(sg_fd, &io_hdr[k], sizeof(sg_io_hdr_t)) < 0) {
- perror("sg_queue_tst: Inquiry write error");
+ perror("sg_queue_tst: sg write error");
close(sg_fd);
return 1;
}
@@ -121,7 +130,7 @@ int main(int argc, char * argv[])
memset(&rio_hdr, 0, sizeof(sg_io_hdr_t));
rio_hdr.interface_id = 'S';
if (read(sg_fd, &rio_hdr, sizeof(sg_io_hdr_t)) < 0) {
- perror("sg_queue_tst: Inquiry read error");
+ perror("sg_queue_tst: sg read error");
close(sg_fd);
return 1;
}
@@ -132,11 +141,11 @@ int main(int argc, char * argv[])
ok = 1;
break;
case SG_LIB_CAT_RECOVERED:
- printf("Recovered error on INQUIRY, continuing\n");
+ printf("Recovered error, continuing\n");
ok = 1;
break;
default: /* won't bother decoding other categories */
- sg_chk_n_print3("INQUIRY command error", &rio_hdr, 1);
+ sg_chk_n_print3("command error", &rio_hdr, 1);
break;
}