aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2010-03-21 02:14:23 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2010-03-21 02:14:23 +0000
commit78fa03f00a95d2717da65884237405731340336a (patch)
treed699f4337a38a8b58a6f32b6e8db65cb4931a333 /examples
parent14caf8f4de1225f7cf56e4131a3b1cbc5535b1b9 (diff)
downloadsg3_utils-78fa03f00a95d2717da65884237405731340336a.tar.gz
add examples/sg_queue_tst for SG_FLAG_Q_AT_TAIL
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@330 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile16
-rw-r--r--examples/sg_queue_tst.c156
-rw-r--r--examples/sg_simple_aio.c31
3 files changed, 193 insertions, 10 deletions
diff --git a/examples/Makefile b/examples/Makefile
index 641e1f78..98aa1cce 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -12,8 +12,8 @@ EXECS = sg_simple1 sg_simple2 sg_simple3 sg_simple4 sg_simple16 \
sg__sat_identify sg__sat_phy_event sg__sat_set_features \
sg_sat_chk_power sg_sat_smart_rd_data
-# EXECS = sg_simple1 sg_simple2 sg_simple3 sg_simple4 sg_simple16 \
-# sg_simple_aio sg_iovec_tst scsi_inquiry sg_excl
+EXTRAS = sg_simple_aio sg_queue_tst
+
MAN_PGS =
MAN_PREF = man8
@@ -31,12 +31,14 @@ LIBFILESNEW = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_pt_linux.o
all: $(EXECS)
+extras: $(EXTRAS)
+
depend dep:
for i in *.c; do $(CC) $(INCLUDES) $(CFLAGS) -M $$i; \
done > .depend
clean:
- /bin/rm -f *.o $(EXECS) core .depend
+ /bin/rm -f *.o $(EXECS) $(EXTRAS) core .depend
sg_simple1: sg_simple1.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
@@ -53,8 +55,11 @@ sg_simple4: sg_simple4.o $(LIBFILESOLD)
sg_simple16: sg_simple16.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
+# sg_simple_aio: sg_simple_aio.o $(LIBFILESOLD)
+# $(LD) -o $@ $(LDFLAGS) $^ -l aio
+
sg_simple_aio: sg_simple_aio.o $(LIBFILESOLD)
- $(LD) -o $@ $(LDFLAGS) $^ -l aio
+ $(LD) -o $@ $(LDFLAGS) $^
sg_iovec_tst: sg_iovec_tst.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
@@ -86,6 +91,9 @@ sg_sat_chk_power: sg_sat_chk_power.o $(LIBFILESOLD)
sg_sat_smart_rd_data: sg_sat_smart_rd_data.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
+sg_queue_tst: sg_queue_tst.o $(LIBFILESOLD)
+ $(LD) -o $@ $(LDFLAGS) $^
+
install: $(EXECS)
install -d $(INSTDIR)
for name in $^; \
diff --git a/examples/sg_queue_tst.c b/examples/sg_queue_tst.c
new file mode 100644
index 00000000..d7739c44
--- /dev/null
+++ b/examples/sg_queue_tst.c
@@ -0,0 +1,156 @@
+#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>
+
+
+#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: sg_queue_tst [-t] <sg_device>
+ -t queue at tail
+
+ Version 0.90 (20100320)
+
+*/
+
+#define INQ_REPLY_LEN 96
+#define INQ_CMD_LEN 6
+#define SDIAG_CMD_LEN 6
+
+#define EBUFF_SZ 256
+
+#ifndef SG_FLAG_Q_AT_TAIL
+#define SG_FLAG_Q_AT_TAIL 0x10
+#endif
+
+
+int main(int argc, char * argv[])
+{
+ int sg_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];
+ sg_io_hdr_t io_hdr[16];
+ sg_io_hdr_t rio_hdr;
+ char * file_name = 0;
+ char ebuff[EBUFF_SZ];
+ unsigned char sense_buffer[16][32];
+ 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: 'sg_queue_tst [-t] <sg_device>'\n");
+ return 1;
+ }
+
+ /* An access mode of O_RDWR is required for write()/read() interface */
+ if ((sg_fd = open(file_name, O_RDWR)) < 0) {
+ snprintf(ebuff, EBUFF_SZ,
+ "sg_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(sg_io_hdr_t));
+ io_hdr[k].interface_id = 'S';
+ /* io_hdr[k].iovec_count = 0; */ /* memset takes care of this */
+ io_hdr[k].mx_sb_len = (unsigned char)sizeof(sense_buffer);
+ if (0 == (k % 3)) {
+ io_hdr[k].cmd_len = sizeof(sdiagCmdBlk);
+ io_hdr[k].cmdp = sdiagCmdBlk;
+ io_hdr[k].dxfer_direction = SG_DXFER_NONE;
+ } else {
+ io_hdr[k].cmd_len = sizeof(inqCmdBlk);
+ io_hdr[k].cmdp = inqCmdBlk;
+ io_hdr[k].dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr[k].dxfer_len = INQ_REPLY_LEN;
+ io_hdr[k].dxferp = inqBuff[k];
+ }
+ io_hdr[k].sbp = sense_buffer[k];
+ 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;
+ /* 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");
+ close(sg_fd);
+ return 1;
+ }
+ }
+ /* sleep(3); */
+ for (k = 0; k < 16; ++k) {
+ 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");
+ close(sg_fd);
+ return 1;
+ }
+ /* now for the error processing */
+ ok = 0;
+ switch (sg_err_category3(&rio_hdr)) {
+ case SG_LIB_CAT_CLEAN:
+ ok = 1;
+ break;
+ case SG_LIB_CAT_RECOVERED:
+ printf("Recovered error on INQUIRY, continuing\n");
+ ok = 1;
+ break;
+ default: /* won't bother decoding other categories */
+ sg_chk_n_print3("INQUIRY command error", &rio_hdr, 1);
+ break;
+ }
+
+ if (ok) { /* output result if it is available */
+ /* if (0 == rio_hdr.pack_id) */
+ if (0 == (rio_hdr.pack_id % 3))
+ printf("SEND DIAGNOSTIC %d duration=%u\n", rio_hdr.pack_id,
+ rio_hdr.duration);
+ else
+ printf("INQUIRY %d duration=%u\n", rio_hdr.pack_id,
+ rio_hdr.duration);
+ }
+ }
+
+ close(sg_fd);
+ return 0;
+}
diff --git a/examples/sg_simple_aio.c b/examples/sg_simple_aio.c
index 009c3fda..e4e8622f 100644
--- a/examples/sg_simple_aio.c
+++ b/examples/sg_simple_aio.c
@@ -7,15 +7,29 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+
+/*
+ * To use "aio" then uncomment the 'WANT_AIO' define.
+ * Depending on the distribution libaio and libaio-dev packages
+ * may need to be loaded.
+ * If WANT_AIO is defined then a '-laio' term will most likely
+ * be required in the Makefile.
+ */
+/* #define WANT_AIO 1 */
+
+#ifdef WANT_AIO
#include <libaio.h>
+#endif
+
#include "sg_lib.h"
+#include "sg_io_linux.h"
#include "sg_linux_inc.h"
/* This is a simple program executing a SCSI INQUIRY command and a
TEST UNIT READY command using the SCSI generic (sg) driver
This variant to test async I/O.
-* Copyright (C) 2003 D. Gilbert
+* Copyright (C) 2003-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)
@@ -23,7 +37,7 @@
Invocation: sg_simple_aio [-x] <sg_device>
- Version 0.91 (20031109)
+ Version 0.92 (20100320)
6 byte INQUIRY command:
[0x12][ |lu][pg cde][res ][al len][cntrl ]
@@ -39,10 +53,15 @@
#define EBUFF_SZ 256
+
+
+#ifdef WANT_AIO
void my_io_callback(io_context_t ctx, struct iocb *iocb, long res, long res2)
{
printf("my_io_callback: res=%ld, res2=%ld\n", res, res2);
}
+#endif
+
int main(int argc, char * argv[])
{
@@ -82,7 +101,7 @@ int main(int argc, char * argv[])
/* An access mode of O_RDWR is required for write()/read() interface */
if ((sg_fd = open(file_name, O_RDWR)) < 0) {
snprintf(ebuff, EBUFF_SZ,
- "sg_simple_aio: error opening file: %s", file_name);
+ "sg_simple_aio: error opening file: %s", file_name);
perror(ebuff);
return 1;
}
@@ -110,7 +129,7 @@ int main(int argc, char * argv[])
/* io_hdr.pack_id = 0; */
/* io_hdr.usr_ptr = NULL; */
-#if 1
+#if WANT_AIO
{
struct iocb a_iocb;
struct iocb * iocb_arr[1];
@@ -157,7 +176,7 @@ int main(int argc, char * argv[])
ok = 1;
break;
default: /* won't bother decoding other categories */
- sg_chk_n_print3("INQUIRY command error", &io_hdr);
+ sg_chk_n_print3("INQUIRY command error", &io_hdr, 1);
break;
}
@@ -201,7 +220,7 @@ int main(int argc, char * argv[])
ok = 1;
break;
default: /* won't bother decoding other categories */
- sg_chk_n_print3("Test Unit Ready command error", &io_hdr);
+ sg_chk_n_print3("Test Unit Ready command error", &io_hdr, 1);
break;
}