aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--README2
-rw-r--r--README.win328
-rw-r--r--debian/changelog2
-rw-r--r--include/sg_pt.h12
-rw-r--r--lib/sg_pt_common.c4
-rw-r--r--lib/sg_pt_win32.c310
-rw-r--r--sg3_utils.spec2
8 files changed, 251 insertions, 93 deletions
diff --git a/ChangeLog b/ChangeLog
index d856a8c5..9dfc827a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,13 +2,15 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.31 [20110206] [svn: r376]
+Changelog for sg3_utils-1.31 [20110206] [svn: r377]
- sg_decode_sense: new utility to decode sense data
- sg_vpd: LB provisioning + Block limits pages (sbc3r26)
- sync asc/ascq and version descriptors with spc4r28
- sg_lib: implement forwarded sense data descriptor
- sg_lib, sg_turs, sg_format: more precision for progress
indication (two places after decimal point)
+ - sg_lib(win32): add runtime selection of SPT direct or
+ indirect interface
Changelog for sg3_utils-1.30 [20101111] [svn: r363]
- sg_referrals: new utility for REPORT REFERRALS
diff --git a/README b/README
index fb65bea0..b5c71119 100644
--- a/README
+++ b/README
@@ -348,4 +348,4 @@ See http://sg.danny.cz/sg/tools.html
Doug Gilbert
-25th January 2011
+6th February 2011
diff --git a/README.win32 b/README.win32
index b7f54047..2c329a09 100644
--- a/README.win32
+++ b/README.win32
@@ -103,6 +103,12 @@ The package can be built using the direct variant with:
rather than:
./configure
prior to the 'make' call.
+In sg3_utils version 1.31 runtime selection of the direct or indirect
+interface was added with the scsi_pt_win32_direct(int state_direct)
+function declared in sg_pt.h. The default is indirect unless
+'./configure --enable-win32-spt-direct' was used in the build. If
+'state_direct' is 1 then the direct interface is used and if it is 0
+the indirect interface is used.
Details
=======
@@ -197,4 +203,4 @@ mode" with the setmode() Windows command.
Doug Gilbert
-5th December 2010
+6th February 2011
diff --git a/debian/changelog b/debian/changelog
index 849799f6..b53733b8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.31-0.1) unstable; urgency=low
* New upstream version
- -- Doug Gilbert <dgilbert@interlog.com> Tue, 25 Jan 2011 19:00:00 -0500
+ -- Doug Gilbert <dgilbert@interlog.com> Sun, 06 Feb 2011 11:00:00 -0500
sg3-utils (1.30-0.1) unstable; urgency=low
diff --git a/include/sg_pt.h b/include/sg_pt.h
index cee5e670..d3ae7d50 100644
--- a/include/sg_pt.h
+++ b/include/sg_pt.h
@@ -2,7 +2,7 @@
#define SG_PT_H
/*
- * Copyright (c) 2005-2010 Douglas Gilbert.
+ * Copyright (c) 2005-2011 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -129,6 +129,16 @@ extern int get_scsi_pt_duration_ms(const struct sg_pt_base * objp);
* call there should be one destruct_scsi_pt_obj(). */
extern void destruct_scsi_pt_obj(struct sg_pt_base * objp);
+#ifdef SG_LIB_WIN32
+#define SG_LIB_WIN32_DIRECT 1
+
+/* Request SPT direct interface when state_direct is 1, state_direct set
+ * to 0 for the SPT indirect interface. Default setting selected by build
+ * (i.e. library compile time) and is usually indirect. */
+extern void scsi_pt_win32_direct(int state_direct);
+
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/sg_pt_common.c b/lib/sg_pt_common.c
index 738d612d..fe9e9c0c 100644
--- a/lib/sg_pt_common.c
+++ b/lib/sg_pt_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2010 Douglas Gilbert.
+ * Copyright (c) 2009-2011 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -14,7 +14,7 @@
#endif
-static const char * scsi_pt_version_str = "2.06 20100812";
+static const char * scsi_pt_version_str = "2.07 20110206";
const char *
scsi_pt_version()
diff --git a/lib/sg_pt_win32.c b/lib/sg_pt_win32.c
index 78ea6248..d483a5a6 100644
--- a/lib/sg_pt_win32.c
+++ b/lib/sg_pt_win32.c
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2006-2010 Douglas Gilbert.
+ * Copyright (c) 2006-2011 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
*/
-/* sg_pt_win32 version 1.11 20100321 */
+/* sg_pt_win32 version 1.12 20110206 */
#include <stdio.h>
#include <stdlib.h>
@@ -40,7 +40,9 @@
*
* This code will default to indirect (i.e. double buffered) access
* unless the WIN32_SPT_DIRECT preprocessor constant is defined in
- * config.h .
+ * config.h . In version 1.12 runtime selection of direct and indirect
+ * access was added; the default is still determined by the
+ * WIN32_SPT_DIRECT preprocessor constant.
*/
#define DEF_TIMEOUT 60 /* 60 seconds */
@@ -69,12 +71,11 @@ struct sg_pt_win32_scsi {
int in_err;
int os_err; /* pseudo unix error */
int transport_err; /* windows error number */
-#ifdef WIN32_SPT_DIRECT
- SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
-#else
- /* Last entry in structure so data buffer can be extended */
- SCSI_PASS_THROUGH_WITH_BUFFERS swb;
-#endif
+ union {
+ SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb_d;
+ /* Last entry in structure so data buffer can be extended */
+ SCSI_PASS_THROUGH_WITH_BUFFERS swb_i;
+ };
};
/* embed pointer so can change on fly if (non-direct) data buffer
@@ -83,6 +84,21 @@ struct sg_pt_base {
struct sg_pt_win32_scsi * implp;
};
+#ifdef WIN32_SPT_DIRECT
+static int spt_direct = 1;
+#else
+static int spt_direct = 0;
+#endif
+
+
+/* Request SPT direct interface when state_direct is 1, state_direct set
+ * to 0 for the SPT indirect interface. */
+void
+scsi_pt_win32_direct(int state_direct)
+{
+ spt_direct = state_direct;
+}
+
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
@@ -226,11 +242,19 @@ construct_scsi_pt_obj()
psp = (struct sg_pt_win32_scsi *)calloc(sizeof(struct sg_pt_win32_scsi),
1);
if (psp) {
- psp->swb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
- psp->swb.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
- psp->swb.spt.SenseInfoOffset =
+ if (spt_direct) {
+ psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
+ psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
+ psp->swb_d.spt.SenseInfoOffset =
+ offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
+ psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT;
+ } else {
+ psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
+ psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
+ psp->swb_i.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
- psp->swb.spt.TimeOutValue = DEF_TIMEOUT;
+ psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT;
+ }
vp = malloc(sizeof(struct sg_pt_win32_scsi *)); // yes a pointer
if (vp)
vp->implp = psp;
@@ -260,11 +284,19 @@ clear_scsi_pt_obj(struct sg_pt_base * vp)
if (psp) {
memset(psp, 0, sizeof(struct sg_pt_win32_scsi));
- psp->swb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
- psp->swb.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
- psp->swb.spt.SenseInfoOffset =
+ if (spt_direct) {
+ psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
+ psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
+ psp->swb_d.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
- psp->swb.spt.TimeOutValue = DEF_TIMEOUT;
+ psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT;
+ } else {
+ psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
+ psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
+ psp->swb_i.spt.SenseInfoOffset =
+ offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
+ psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT;
+ }
}
}
@@ -274,14 +306,25 @@ set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
{
struct sg_pt_win32_scsi * psp = vp->implp;
- if (psp->swb.spt.CdbLength > 0)
- ++psp->in_err;
- if (cdb_len > (int)sizeof(psp->swb.spt.Cdb)) {
- ++psp->in_err;
- return;
+ if (spt_direct) {
+ if (psp->swb_d.spt.CdbLength > 0)
+ ++psp->in_err;
+ if (cdb_len > (int)sizeof(psp->swb_d.spt.Cdb)) {
+ ++psp->in_err;
+ return;
+ }
+ memcpy(psp->swb_d.spt.Cdb, cdb, cdb_len);
+ psp->swb_d.spt.CdbLength = cdb_len;
+ } else {
+ if (psp->swb_i.spt.CdbLength > 0)
+ ++psp->in_err;
+ if (cdb_len > (int)sizeof(psp->swb_i.spt.Cdb)) {
+ ++psp->in_err;
+ return;
+ }
+ memcpy(psp->swb_i.spt.Cdb, cdb, cdb_len);
+ psp->swb_i.spt.CdbLength = cdb_len;
}
- memcpy(psp->swb.spt.Cdb, cdb, cdb_len);
- psp->swb.spt.CdbLength = cdb_len;
}
void
@@ -309,7 +352,10 @@ set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
if (dxfer_len > 0) {
psp->dxferp = dxferp;
psp->dxfer_len = dxfer_len;
- psp->swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
+ if (spt_direct)
+ psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_IN;
+ else
+ psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_IN;
}
}
@@ -325,7 +371,10 @@ set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
if (dxfer_len > 0) {
psp->dxferp = (unsigned char *)dxferp;
psp->dxfer_len = dxfer_len;
- psp->swb.spt.DataIn = SCSI_IOCTL_DATA_OUT;
+ if (spt_direct)
+ psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_OUT;
+ else
+ psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_OUT;
}
}
@@ -370,11 +419,12 @@ set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
flags = flags;
}
-/* Executes SCSI command (or at least forwards it to lower layers).
- * Clears os_err field prior to active call (whose result may set it
- * again). */
+/* Executes SCSI command (or at least forwards it to lower layers)
+ * using direct interface. Clears os_err field prior to active call (whose
+ * result may set it again). */
int
-do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
+do_scsi_pt_direct(struct sg_pt_base * vp, int device_fd, int time_secs,
+ int verbose)
{
int index = device_fd - WIN32_FDOFFSET;
struct sg_pt_win32_scsi * psp = vp->implp;
@@ -390,7 +440,7 @@ do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n");
return SCSI_PT_DO_BAD_PARAMS;
}
- if (0 == psp->swb.spt.CdbLength) {
+ if (0 == psp->swb_d.spt.CdbLength) {
if (verbose)
fprintf(sg_warnings_strm, "No command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
@@ -410,17 +460,110 @@ do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
psp->os_err = ENODEV;
return -psp->os_err;
}
-#ifdef WIN32_SPT_DIRECT
- psp->swb.spt.Length = sizeof (SCSI_PASS_THROUGH_DIRECT);
-#else
- if (psp->dxfer_len > (int)sizeof(psp->swb.ucDataBuf)) {
- int extra = psp->dxfer_len - (int)sizeof(psp->swb.ucDataBuf);
+ psp->swb_d.spt.Length = sizeof (SCSI_PASS_THROUGH_DIRECT);
+ psp->swb_d.spt.PathId = shp->bus;
+ psp->swb_d.spt.TargetId = shp->target;
+ psp->swb_d.spt.Lun = shp->lun;
+ psp->swb_d.spt.TimeOutValue = time_secs;
+ psp->swb_d.spt.DataTransferLength = psp->dxfer_len;
+ if (verbose > 4) {
+ fprintf(stderr, " spt_direct, adapter: %s Length=%d ScsiStatus=%d "
+ "PathId=%d TargetId=%d Lun=%d\n", shp->adapter,
+ (int)psp->swb_d.spt.Length,
+ (int)psp->swb_d.spt.ScsiStatus, (int)psp->swb_d.spt.PathId,
+ (int)psp->swb_d.spt.TargetId, (int)psp->swb_d.spt.Lun);
+ fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d "
+ "DataTransferLength=%lu\n",
+ (int)psp->swb_d.spt.CdbLength,
+ (int)psp->swb_d.spt.SenseInfoLength,
+ (int)psp->swb_d.spt.DataIn,
+ psp->swb_d.spt.DataTransferLength);
+ fprintf(stderr, " TimeOutValue=%lu SenseInfoOffset=%lu\n",
+ psp->swb_d.spt.TimeOutValue, psp->swb_d.spt.SenseInfoOffset);
+ }
+ psp->swb_d.spt.DataBuffer = psp->dxferp;
+ status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT,
+ &psp->swb_d,
+ sizeof(psp->swb_d),
+ &psp->swb_d,
+ sizeof(psp->swb_d),
+ &returned,
+ NULL);
+ if (! status) {
+ psp->transport_err = GetLastError();
+ if (verbose)
+ fprintf(sg_warnings_strm, "Windows DeviceIoControl error=%d\n",
+ psp->transport_err);
+ psp->os_err = EIO;
+ return 0; /* let app find transport error */
+ }
+
+ psp->scsi_status = psp->swb_d.spt.ScsiStatus;
+ if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) ||
+ (SAM_STAT_COMMAND_TERMINATED == psp->scsi_status))
+ memcpy(psp->sensep, psp->swb_d.ucSenseBuf, psp->sense_len);
+ else
+ psp->sense_len = 0;
+ psp->sense_resid = 0;
+ if ((psp->dxfer_len > 0) && (psp->swb_d.spt.DataTransferLength > 0))
+ psp->resid = psp->dxfer_len - psp->swb_d.spt.DataTransferLength;
+ else
+ psp->resid = 0;
+
+ return 0;
+}
+
+/* Executes SCSI command (or at least forwards it to lower layers) using
+ * indirect interface. Clears os_err field prior to active call (whose
+ * result may set it again). */
+static int
+do_scsi_pt_indirect(struct sg_pt_base * vp, int device_fd, int time_secs,
+ int verbose)
+{
+ int index = device_fd - WIN32_FDOFFSET;
+ struct sg_pt_win32_scsi * psp = vp->implp;
+ struct sg_pt_handle * shp;
+ BOOL status;
+ ULONG returned;
+
+ if (NULL == sg_warnings_strm)
+ sg_warnings_strm = stderr;
+ psp->os_err = 0;
+ if (psp->in_err) {
+ if (verbose)
+ fprintf(sg_warnings_strm, "Replicated or unused "
+ "set_scsi_pt...\n");
+ return SCSI_PT_DO_BAD_PARAMS;
+ }
+ if (0 == psp->swb_i.spt.CdbLength) {
+ if (verbose)
+ fprintf(sg_warnings_strm, "No command (cdb) given\n");
+ return SCSI_PT_DO_BAD_PARAMS;
+ }
+
+ index = device_fd - WIN32_FDOFFSET;
+ if ((index < 0) || (index >= WIN32_FDOFFSET)) {
+ if (verbose)
+ fprintf(sg_warnings_strm, "Bad file descriptor\n");
+ psp->os_err = ENODEV;
+ return -psp->os_err;
+ }
+ shp = handle_arr + index;
+ if (0 == shp->in_use) {
+ if (verbose)
+ fprintf(sg_warnings_strm, "File descriptor closed??\n");
+ psp->os_err = ENODEV;
+ return -psp->os_err;
+ }
+ if (psp->dxfer_len > (int)sizeof(psp->swb_i.ucDataBuf)) {
+ int extra = psp->dxfer_len - (int)sizeof(psp->swb_i.ucDataBuf);
struct sg_pt_win32_scsi * epsp;
if (verbose > 4)
- fprintf(sg_warnings_strm, "dxfer_len (%d) too large for initial "
- "data buffer (%d bytes), try enlarging\n", psp->dxfer_len,
- sizeof(psp->swb.ucDataBuf));
+ fprintf(sg_warnings_strm, "spt_indirect: dxfer_len (%d) too "
+ "large for initial data\n buffer (%d bytes), try "
+ "enlarging\n", psp->dxfer_len,
+ sizeof(psp->swb_i.ucDataBuf));
epsp = (struct sg_pt_win32_scsi *)
calloc(sizeof(struct sg_pt_win32_scsi) + extra, 1);
if (NULL == epsp) {
@@ -434,54 +577,41 @@ do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
vp->implp = epsp;
psp = epsp;
}
- psp->swb.spt.Length = sizeof (SCSI_PASS_THROUGH);
- psp->swb.spt.DataBufferOffset =
+ psp->swb_i.spt.Length = sizeof (SCSI_PASS_THROUGH);
+ psp->swb_i.spt.DataBufferOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf);
-#endif
- psp->swb.spt.PathId = shp->bus;
- psp->swb.spt.TargetId = shp->target;
- psp->swb.spt.Lun = shp->lun;
- psp->swb.spt.TimeOutValue = time_secs;
- psp->swb.spt.DataTransferLength = psp->dxfer_len;
+ psp->swb_i.spt.PathId = shp->bus;
+ psp->swb_i.spt.TargetId = shp->target;
+ psp->swb_i.spt.Lun = shp->lun;
+ psp->swb_i.spt.TimeOutValue = time_secs;
+ psp->swb_i.spt.DataTransferLength = psp->dxfer_len;
if (verbose > 4) {
- fprintf(stderr, " spt:: adapter: %s Length=%d ScsiStatus=%d "
+ fprintf(stderr, " spt_indirect, adapter: %s Length=%d ScsiStatus=%d "
"PathId=%d TargetId=%d Lun=%d\n", shp->adapter,
- (int)psp->swb.spt.Length,
- (int)psp->swb.spt.ScsiStatus, (int)psp->swb.spt.PathId,
- (int)psp->swb.spt.TargetId, (int)psp->swb.spt.Lun);
+ (int)psp->swb_i.spt.Length,
+ (int)psp->swb_i.spt.ScsiStatus, (int)psp->swb_i.spt.PathId,
+ (int)psp->swb_i.spt.TargetId, (int)psp->swb_i.spt.Lun);
fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d "
"DataTransferLength=%lu\n",
- (int)psp->swb.spt.CdbLength, (int)psp->swb.spt.SenseInfoLength,
- (int)psp->swb.spt.DataIn, psp->swb.spt.DataTransferLength);
-#ifdef WIN32_SPT_DIRECT
- fprintf(stderr, " TimeOutValue=%lu SenseInfoOffset=%lu\n",
- psp->swb.spt.TimeOutValue, psp->swb.spt.SenseInfoOffset);
-#else
+ (int)psp->swb_i.spt.CdbLength,
+ (int)psp->swb_i.spt.SenseInfoLength,
+ (int)psp->swb_i.spt.DataIn,
+ psp->swb_i.spt.DataTransferLength);
fprintf(stderr, " TimeOutValue=%lu DataBufferOffset=%lu "
- "SenseInfoOffset=%lu\n", psp->swb.spt.TimeOutValue,
- psp->swb.spt.DataBufferOffset, psp->swb.spt.SenseInfoOffset);
-#endif
+ "SenseInfoOffset=%lu\n", psp->swb_i.spt.TimeOutValue,
+ psp->swb_i.spt.DataBufferOffset,
+ psp->swb_i.spt.SenseInfoOffset);
}
-#ifdef WIN32_SPT_DIRECT
- psp->swb.spt.DataBuffer = psp->dxferp;
- status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT,
- &psp->swb,
- sizeof(psp->swb),
- &psp->swb,
- sizeof(psp->swb),
- &returned,
- NULL);
-#else
- if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_OUT == psp->swb.spt.DataIn))
- memcpy(psp->swb.ucDataBuf, psp->dxferp, psp->dxfer_len);
+ if ((psp->dxfer_len > 0) &&
+ (SCSI_IOCTL_DATA_OUT == psp->swb_i.spt.DataIn))
+ memcpy(psp->swb_i.ucDataBuf, psp->dxferp, psp->dxfer_len);
status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH,
- &psp->swb,
- sizeof(psp->swb),
- &psp->swb,
- sizeof(psp->swb),
+ &psp->swb_i,
+ sizeof(psp->swb_i),
+ &psp->swb_i,
+ sizeof(psp->swb_i),
&returned,
NULL);
-#endif
if (! status) {
psp->transport_err = GetLastError();
if (verbose)
@@ -490,26 +620,36 @@ do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
psp->os_err = EIO;
return 0; /* let app find transport error */
}
-#ifndef WIN32_SPT_DIRECT
- if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_IN == psp->swb.spt.DataIn))
- memcpy(psp->dxferp, psp->swb.ucDataBuf, psp->dxfer_len);
-#endif
+ if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_IN == psp->swb_i.spt.DataIn))
+ memcpy(psp->dxferp, psp->swb_i.ucDataBuf, psp->dxfer_len);
- psp->scsi_status = psp->swb.spt.ScsiStatus;
+ psp->scsi_status = psp->swb_i.spt.ScsiStatus;
if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == psp->scsi_status))
- memcpy(psp->sensep, psp->swb.ucSenseBuf, psp->sense_len);
+ memcpy(psp->sensep, psp->swb_i.ucSenseBuf, psp->sense_len);
else
psp->sense_len = 0;
psp->sense_resid = 0;
- if ((psp->dxfer_len > 0) && (psp->swb.spt.DataTransferLength > 0))
- psp->resid = psp->dxfer_len - psp->swb.spt.DataTransferLength;
+ if ((psp->dxfer_len > 0) && (psp->swb_i.spt.DataTransferLength > 0))
+ psp->resid = psp->dxfer_len - psp->swb_i.spt.DataTransferLength;
else
psp->resid = 0;
return 0;
}
+/* Executes SCSI command (or at least forwards it to lower layers).
+ * Clears os_err field prior to active call (whose result may set it
+ * again). */
+int
+do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
+{
+ if (spt_direct)
+ return do_scsi_pt_direct(vp, device_fd, time_secs, verbose);
+ else
+ return do_scsi_pt_indirect(vp, device_fd, time_secs, verbose);
+}
+
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 8d17cb64..168b0b59 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Tue Jan 25 2011 - dgilbert at interlog dot com
+* Sun Feb 06 2011 - dgilbert at interlog dot com
- add sg_decode_sense; track t10 changes
* sg3_utils-1.31