aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2015-02-07 20:28:00 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2015-02-07 20:28:00 +0000
commitcc44a8ffd8b6c05d6dcb96accf3e3ebcc16a9cf4 (patch)
tree43dfce42172b40bbfd62ae5c474819853dafd89e /examples
parent8eb6e683154b2538f67bc379824c1c64dc7e10cb (diff)
downloadsg3_utils-cc44a8ffd8b6c05d6dcb96accf3e3ebcc16a9cf4.tar.gz
sg_simple_aio.c: remove; sg_iovec_tst.c: improve
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@633 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile8
-rw-r--r--examples/sg_iovec_tst.c130
-rw-r--r--examples/sg_simple_aio.c239
3 files changed, 103 insertions, 274 deletions
diff --git a/examples/Makefile b/examples/Makefile
index 7fb43404..2f02328f 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -12,7 +12,7 @@ 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
-EXTRAS = sg_simple_aio sg_queue_tst sgq_dd
+EXTRAS = sg_queue_tst sgq_dd
BSG_EXTRAS = bsg_queue_tst
@@ -60,12 +60,6 @@ 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) $^
-
sg_iovec_tst: sg_iovec_tst.o $(LIBFILESOLD)
$(LD) -o $@ $(LDFLAGS) $^
diff --git a/examples/sg_iovec_tst.c b/examples/sg_iovec_tst.c
index 9f8bbe3c..2a924261 100644
--- a/examples/sg_iovec_tst.c
+++ b/examples/sg_iovec_tst.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <poll.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -13,7 +14,7 @@
/* Test code for D. Gilbert's extensions to the Linux OS SCSI generic ("sg")
device driver.
-* Copyright (C) 2003-2007 D. Gilbert
+* Copyright (C) 2003-2015 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)
@@ -24,7 +25,7 @@
normal file. The purpose is to test the sg_iovec mechanism within the
sg_io_hdr structure.
- Version 0.12 (20070121)
+ Version 0.13 (20150204)
*/
@@ -38,15 +39,32 @@
struct sg_iovec iovec[IOVEC_ELEMS];
+
+static void
+usage(void)
+{
+ printf("Usage: sg_iovec_tst [-a] [-b=bs] -c=num [-e=es] [-h]\n"
+ " <generic_device> <output_filename>\n");
+ printf(" where: -a async sg use (def: use ioctl(SGIO) )\n");
+ printf(" -b=bs block size (default 512 Bytes)\n");
+ printf(" -c=num count of blocks to transfer\n");
+ printf(" -e=es iovec element size (def: 509)\n");
+ printf(" -h this usage message\n");
+ printf(" reads from <generic_device> and sends to "
+ "<output_filename>\nUses iovec (a scatter list) in linear "
+ "mode\n");
+}
+
/* Returns 0 if everything ok */
-int sg_read(int sg_fd, unsigned char * buff, int num_blocks, int from_block,
- int bs)
+static int sg_read(int sg_fd, unsigned char * buff, int num_blocks,
+ int from_block, int bs, int elem_size, int async)
{
unsigned char rdCmd[10] = {READ_10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
+ struct pollfd a_poll;
int dxfer_len = bs * num_blocks;
- int k, pos, rem;
+ int k, pos, rem, res;
rdCmd[2] = (unsigned char)((from_block >> 24) & 0xff);
rdCmd[3] = (unsigned char)((from_block >> 16) & 0xff);
@@ -57,11 +75,11 @@ int sg_read(int sg_fd, unsigned char * buff, int num_blocks, int from_block,
for (k = 0, pos = 0, rem = dxfer_len; k < IOVEC_ELEMS; ++k) {
iovec[k].iov_base = buff + pos;
- iovec[k].iov_len = (rem > A_PRIME) ? A_PRIME : rem;
- if (rem <= A_PRIME)
+ iovec[k].iov_len = (rem > elem_size) ? elem_size : rem;
+ if (rem <= elem_size)
break;
- pos += A_PRIME;
- rem -= A_PRIME;
+ pos += elem_size;
+ rem -= elem_size;
}
if (k >= IOVEC_ELEMS) {
fprintf(stderr, "Can't fit dxfer_len=%d bytes in iovec\n", dxfer_len);
@@ -80,7 +98,39 @@ int sg_read(int sg_fd, unsigned char * buff, int num_blocks, int from_block,
io_hdr.timeout = DEF_TIMEOUT;
io_hdr.pack_id = from_block;
- if (ioctl(sg_fd, SG_IO, &io_hdr)) {
+ if (async) {
+ res = write(sg_fd, &io_hdr, sizeof(io_hdr));
+ if (res < 0) {
+ perror("write(<sg_device>), error");
+ return -1;
+ } else if (res < (int)sizeof(io_hdr)) {
+ fprintf(stderr, "write(<sg_device>) returned %d, expected %d\n",
+ res, (int)sizeof(io_hdr));
+ return -1;
+ }
+ a_poll.fd = sg_fd;
+ a_poll.events = POLLIN;
+ a_poll.revents = 0;
+ res = poll(&a_poll, 1, 2000 /* millisecs */ );
+ if (res < 0) {
+ perror("poll error on <sg_device>");
+ return -1;
+ }
+ if (0 == (POLLIN & a_poll.revents)) {
+ fprintf(stderr, "strange, poll() completed without data to "
+ "read\n");
+ return -1;
+ }
+ res = read(sg_fd, &io_hdr, sizeof(io_hdr));
+ if (res < 0) {
+ perror("read(<sg_device>), error");
+ return -1;
+ } else if (res < (int)sizeof(io_hdr)) {
+ fprintf(stderr, "read(<sg_device>) returned %d, expected %d\n",
+ res, (int)sizeof(io_hdr));
+ return -1;
+ }
+ } else if (ioctl(sg_fd, SG_IO, &io_hdr)) {
perror("reading (SG_IO) on sg device, error");
return -1;
}
@@ -106,15 +156,19 @@ int main(int argc, char * argv[])
{
int sg_fd, fd, res, j, m, dxfer_len;
unsigned int k, num;
+ int do_async = 0;
int do_help = 0;
int blk_size = 512;
+ int elem_size = A_PRIME;
int count = 0;
char * sg_file_name = 0;
char * out_file_name = 0;
unsigned char * buffp;
for (j = 1; j < argc; ++j) {
- if (0 == strncmp("-b=", argv[j], 3)) {
+ if (0 == strcmp("-a", argv[j]))
+ do_async = 1;
+ else if (0 == strncmp("-b=", argv[j], 3)) {
m = 3;
num = sscanf(argv[j] + m, "%d", &blk_size);
if ((1 != num) || (blk_size <= 0)) {
@@ -122,8 +176,7 @@ int main(int argc, char * argv[])
sg_file_name = 0;
break;
}
- }
- else if (0 == strncmp("-c=", argv[j], 3)) {
+ } else if (0 == strncmp("-c=", argv[j], 3)) {
m = 3;
num = sscanf(argv[j] + m, "%d", &count);
if (1 != num) {
@@ -131,31 +184,49 @@ int main(int argc, char * argv[])
sg_file_name = 0;
break;
}
- }
- else if (0 == strcmp("-h", argv[j]))
+ } else if (0 == strncmp("-e=", argv[j], 3)) {
+ m = 3;
+ num = sscanf(argv[j] + m, "%d", &elem_size);
+ if (1 != num) {
+ printf("Couldn't decode number after '-e' switch\n");
+ sg_file_name = 0;
+ break;
+ }
+ } else if (0 == strcmp("-h", argv[j]))
do_help = 1;
else if (*argv[j] == '-') {
printf("Unrecognized switch: %s\n", argv[j]);
sg_file_name = 0;
break;
- }
- else if (NULL == sg_file_name)
+ } else if (NULL == sg_file_name)
sg_file_name = argv[j];
else
out_file_name = argv[j];
}
- if ((NULL == sg_file_name) || (NULL == out_file_name) || (0 == count)) {
- printf("Usage: sg_iovec_tst [-h] [-b=num] -c=num <generic_device> "
- "<output_filename>\n");
- printf(" where: -h this usage message\n");
- printf(" -b=num block size (default 512 Bytes)\n");
- printf(" -c=num count of blocks to transfer\n");
- printf(" reads from <generic_device> and sends to "
- "<output_filename>\n");
+ if (do_help) {
+ usage();
+ return 0;
+ }
+ if (NULL == sg_file_name) {
+ printf(">>> need sg node name (e.g. /dev/sg3)\n\n");
+ usage();
+ return 1;
+ }
+ if (NULL == out_file_name) {
+ printf(">>> need out filename (to place what is fetched by READ\n\n");
+ usage();
+ return 1;
+ }
+ if (0 == count) {
+ printf(">>> need count of blocks to READ\n\n");
+ usage();
return 1;
}
- sg_fd = open(sg_file_name, O_RDONLY);
+ if (do_async)
+ sg_fd = open(sg_file_name, O_RDWR);
+ else
+ sg_fd = open(sg_file_name, O_RDONLY);
if (sg_fd < 0) {
perror(ME "sg device node open error");
return 1;
@@ -174,12 +245,15 @@ int main(int argc, char * argv[])
dxfer_len = count * blk_size;
buffp = (unsigned char *)malloc(dxfer_len);
if (buffp) {
- if (0 == sg_read(sg_fd, buffp, count, 0, blk_size)) {
+ if (0 == sg_read(sg_fd, buffp, count, 0, blk_size, elem_size,
+ do_async)) {
if (write(fd, buffp, dxfer_len) < 0)
perror(ME "output write failed");
}
free(buffp);
- }
+ } else
+ fprintf(stderr, "user space malloc for %d bytes failed\n",
+ dxfer_len);
res = close(fd);
if (res < 0) {
perror(ME "output file close error");
diff --git a/examples/sg_simple_aio.c b/examples/sg_simple_aio.c
deleted file mode 100644
index 95dfcfa2..00000000
--- a/examples/sg_simple_aio.c
+++ /dev/null
@@ -1,239 +0,0 @@
-#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>
-
-/*
- * 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-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_simple_aio [-x] <sg_device>
-
- Version 0.92 (20100320)
-
-6 byte INQUIRY command:
-[0x12][ |lu][pg cde][res ][al len][cntrl ]
-
-6 byte TEST UNIT READY command:
-[0x00][ |lu][res ][res ][res ][res ]
-
-*/
-
-#define INQ_REPLY_LEN 96
-#define INQ_CMD_LEN 6
-#define TUR_CMD_LEN 6
-
-#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[])
-{
- int sg_fd, k, ok;
- unsigned char inqCmdBlk [INQ_CMD_LEN] =
- {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
- unsigned char turCmdBlk [TUR_CMD_LEN] =
- {0x00, 0, 0, 0, 0, 0};
- unsigned char inqBuff[INQ_REPLY_LEN];
- sg_io_hdr_t io_hdr;
- char * file_name = 0;
- char ebuff[EBUFF_SZ];
- unsigned char sense_buffer[32];
- int do_extra = 0;
-
- for (k = 1; k < argc; ++k) {
- if (0 == memcmp("-x", argv[k], 2))
- do_extra = 1;
- 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_simple_aio [-x] <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_simple_aio: error opening file: %s", file_name);
- perror(ebuff);
- return 1;
- }
- /* Just to be safe, check we have a new sg device by trying an ioctl */
- if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
- printf("sg_simple_aio: %s doesn't seem to be an new sg device\n",
- file_name);
- close(sg_fd);
- return 1;
- }
-
- /* Prepare INQUIRY command */
- memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
- io_hdr.interface_id = 'S';
- io_hdr.cmd_len = sizeof(inqCmdBlk);
- /* io_hdr.iovec_count = 0; */ /* memset takes care of this */
- io_hdr.mx_sb_len = sizeof(sense_buffer);
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
- io_hdr.dxfer_len = INQ_REPLY_LEN;
- io_hdr.dxferp = inqBuff;
- io_hdr.cmdp = inqCmdBlk;
- io_hdr.sbp = sense_buffer;
- io_hdr.timeout = 20000; /* 20000 millisecs == 20 seconds */
- /* io_hdr.flags = 0; */ /* take defaults: indirect IO, etc */
- /* io_hdr.pack_id = 0; */
- /* io_hdr.usr_ptr = NULL; */
-
-#if WANT_AIO
- {
- struct iocb a_iocb;
- struct iocb * iocb_arr[1];
- io_context_t io_ctx;
- int res;
-
- if (0 != (res = io_queue_init(1, &io_ctx))) {
- printf("io_queue_init: failed %s\n", strerror(-res));
- close(sg_fd);
- return 1;
- }
- iocb_arr[0] = &a_iocb;
- io_prep_pwrite(iocb_arr[0], sg_fd, &io_hdr, sizeof(io_hdr), 0);
- io_set_callback(iocb_arr[0], my_io_callback);
- res = io_submit(io_ctx, 1, iocb_arr);
- if (1 != res) {
- printf("io_submit: returned %d\n", res);
- close(sg_fd);
- return 1;
- }
- }
-#else
- if (write(sg_fd, &io_hdr, sizeof(io_hdr)) < 0) {
- perror("sg_simple_aio: Inquiry write error");
- close(sg_fd);
- return 1;
- }
-#endif
- /* sleep(3); */
- if (read(sg_fd, &io_hdr, sizeof(io_hdr)) < 0) {
- perror("sg_simple_aio: Inquiry read error");
- close(sg_fd);
- return 1;
- }
-
- /* now for the error processing */
- ok = 0;
- switch (sg_err_category3(&io_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", &io_hdr, 1);
- break;
- }
-
- if (ok) { /* output result if it is available */
- char * p = (char *)inqBuff;
- int f = (int)*(p + 7);
- printf("Some of the INQUIRY command's results:\n");
- printf(" %.8s %.16s %.4s ", p + 8, p + 16, p + 32);
- printf("[wide=%d sync=%d cmdque=%d sftre=%d]\n",
- !!(f & 0x20), !!(f & 0x10), !!(f & 2), !!(f & 1));
- /* Extra info, not necessary to look at */
- if (do_extra)
- printf("INQUIRY duration=%u millisecs, resid=%d, msg_status=%d\n",
- io_hdr.duration, io_hdr.resid, (int)io_hdr.msg_status);
- }
-
- /* Prepare TEST UNIT READY command */
- memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
- io_hdr.interface_id = 'S';
- io_hdr.cmd_len = sizeof(turCmdBlk);
- io_hdr.mx_sb_len = sizeof(sense_buffer);
- io_hdr.dxfer_direction = SG_DXFER_NONE;
- io_hdr.cmdp = turCmdBlk;
- io_hdr.sbp = sense_buffer;
- io_hdr.timeout = 20000; /* 20000 millisecs == 20 seconds */
-
- if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
- perror("sg_simple_aio: Test Unit Ready SG_IO ioctl error");
- close(sg_fd);
- return 1;
- }
-
- /* now for the error processing */
- ok = 0;
- switch (sg_err_category3(&io_hdr)) {
- case SG_LIB_CAT_CLEAN:
- ok = 1;
- break;
- case SG_LIB_CAT_RECOVERED:
- printf("Recovered error on Test Unit Ready, continuing\n");
- ok = 1;
- break;
- default: /* won't bother decoding other categories */
- sg_chk_n_print3("Test Unit Ready command error", &io_hdr, 1);
- break;
- }
-
- if (ok)
- printf("Test Unit Ready successful so unit is ready!\n");
- else
- printf("Test Unit Ready failed so unit may _not_ be ready!\n");
-
- if (do_extra)
- printf("TEST UNIT READY duration=%u millisecs, resid=%d, "
- "msg_status=%d\n", io_hdr.duration, io_hdr.resid,
- (int)io_hdr.msg_status);
-
- close(sg_fd);
- return 0;
-}