aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--examples/sg_tst_async.cpp35
-rw-r--r--include/sg_unaligned.h116
-rw-r--r--src/sg_scan.c.win3242
4 files changed, 152 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index 3d93e5d3..b91eb316 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ 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.40 [20140821] [svn: r601]
+Changelog for sg3_utils-1.40 [20140827] [svn: r602]
- sg_write_verify: new utility for WRITE AND VERIFY
- sg_senddiag: add --maxlen= option
- sg_copy_results: correct response length calculations
@@ -16,6 +16,7 @@ Changelog for sg3_utils-1.40 [20140821] [svn: r601]
- sg_sat_*: mention t_type and multiple_count fields
- win32: sg_scan: handle larger configurations
- sg_lib: trim trailing spaces in dStrHex() and friends
+ - sg_unaligned.h: add header for building parameters
- examples/sg_tst_async: new Linux sg test utility
Changelog for sg3_utils-1.39 [20140612] [svn: r588]
diff --git a/examples/sg_tst_async.cpp b/examples/sg_tst_async.cpp
index 058af985..afda6185 100644
--- a/examples/sg_tst_async.cpp
+++ b/examples/sg_tst_async.cpp
@@ -55,8 +55,9 @@
#include <sys/stat.h>
#include "sg_lib.h"
#include "sg_io_linux.h"
+#include "sg_unaligned.h"
-static const char * version_str = "1.05 20140821";
+static const char * version_str = "1.06 20140824";
static const char * util_name = "sg_tst_async";
/* This is a test program for checking the async usage of the Linux sg
@@ -346,16 +347,9 @@ start_sg3_cmd(int sg_fd, command2execute cmd2exe, int pack_id, uint64_t lba,
break;
case SCSI_READ16:
np = "READ(16)";
- if (lba > 0xffffffff) {
- r16CmdBlk[2] = (lba >> 56) & 0xff;
- r16CmdBlk[3] = (lba >> 48) & 0xff;
- r16CmdBlk[4] = (lba >> 40) & 0xff;
- r16CmdBlk[5] = (lba >> 32) & 0xff;
- }
- r16CmdBlk[6] = (lba >> 24) & 0xff;
- r16CmdBlk[7] = (lba >> 16) & 0xff;
- r16CmdBlk[8] = (lba >> 8) & 0xff;
- r16CmdBlk[9] = lba & 0xff;
+ if (lba > 0xffffffff)
+ sg_put_unaligned_be32(lba >> 32, &r16CmdBlk[2]);
+ sg_put_unaligned_be32(lba & 0xffffffff, &r16CmdBlk[6]);
pt.cmdp = r16CmdBlk;
pt.cmd_len = sizeof(r16CmdBlk);
pt.dxfer_direction = SG_DXFER_FROM_DEV;
@@ -364,16 +358,9 @@ start_sg3_cmd(int sg_fd, command2execute cmd2exe, int pack_id, uint64_t lba,
break;
case SCSI_WRITE16:
np = "WRITE(16)";
- if (lba > 0xffffffff) {
- w16CmdBlk[2] = (lba >> 56) & 0xff;
- w16CmdBlk[3] = (lba >> 48) & 0xff;
- w16CmdBlk[4] = (lba >> 40) & 0xff;
- w16CmdBlk[5] = (lba >> 32) & 0xff;
- }
- w16CmdBlk[6] = (lba >> 24) & 0xff;
- w16CmdBlk[7] = (lba >> 16) & 0xff;
- w16CmdBlk[8] = (lba >> 8) & 0xff;
- w16CmdBlk[9] = lba & 0xff;
+ if (lba > 0xffffffff)
+ sg_put_unaligned_be32(lba >> 32, &w16CmdBlk[2]);
+ sg_put_unaligned_be32(lba & 0xffffffff, &w16CmdBlk[6]);
pt.cmdp = w16CmdBlk;
pt.cmd_len = sizeof(w16CmdBlk);
pt.dxfer_direction = SG_DXFER_TO_DEV;
@@ -869,10 +856,8 @@ do_read_capacity(const char * dev_name, int block, unsigned int * last_lba,
close(sg_fd);
return -1;
}
- *last_lba = ((rcBuff[0] << 24) | (rcBuff[1] << 16) |
- (rcBuff[2] << 8) | rcBuff[3]);
- *blk_sz = (rcBuff[4] << 24) | (rcBuff[5] << 16) |
- (rcBuff[6] << 8) | rcBuff[7];
+ *last_lba = sg_get_unaligned_be32(&rcBuff[0]);
+ *blk_sz = sg_get_unaligned_be32(&rcBuff[4]);
close(sg_fd);
return 0;
}
diff --git a/include/sg_unaligned.h b/include/sg_unaligned.h
new file mode 100644
index 00000000..c5e5a80b
--- /dev/null
+++ b/include/sg_unaligned.h
@@ -0,0 +1,116 @@
+#ifndef SG_UNALIGNED_H
+#define SG_UNALIGNED_H
+
+/* Borrowed from the Linux kernel, via mhvtl */
+
+/* For the time being, this header contains only cpu order to and from
+ * big endian as required by SCSI standards (www.t10.org). Later, to handle
+ * (S)ATA (www.t13.org) and network traffic, little endian may be added. */
+
+static inline uint16_t __get_unaligned_be16(const uint8_t *p)
+{
+ return p[0] << 8 | p[1];
+}
+
+static inline uint32_t __get_unaligned_be32(const uint8_t *p)
+{
+ return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+}
+
+static inline uint64_t __get_unaligned_be64(const uint8_t *p)
+{
+ return (uint64_t)__get_unaligned_be32(p) << 32 |
+ __get_unaligned_be32(p + 4);
+}
+
+static inline void __put_unaligned_be16(uint16_t val, uint8_t *p)
+{
+ *p++ = val >> 8;
+ *p++ = val;
+}
+
+static inline void __put_unaligned_be32(uint32_t val, uint8_t *p)
+{
+ __put_unaligned_be16(val >> 16, p);
+ __put_unaligned_be16(val, p + 2);
+}
+
+static inline void __put_unaligned_be64(uint64_t val, uint8_t *p)
+{
+ __put_unaligned_be32(val >> 32, p);
+ __put_unaligned_be32(val, p + 4);
+}
+
+static inline uint16_t sg_get_unaligned_be16(const void *p)
+{
+ return __get_unaligned_be16((const uint8_t *)p);
+}
+
+static inline uint32_t sg_get_unaligned_be24(const uint8_t *p)
+{
+ return p[0] << 16 | p[1] << 8 | p[2];
+}
+
+static inline uint32_t sg_get_unaligned_be32(const void *p)
+{
+ return __get_unaligned_be32((const uint8_t *)p);
+}
+
+static inline uint64_t sg_get_unaligned_be64(const void *p)
+{
+ return __get_unaligned_be64((const uint8_t *)p);
+}
+
+static inline void sg_put_unaligned_be16(uint16_t val, void *p)
+{
+ __put_unaligned_be16(val, (uint8_t *)p);
+}
+
+static inline void sg_put_unaligned_be24(uint32_t val, void *p)
+{
+ ((uint8_t *)p)[0] = (val >> 16) & 0xff;
+ ((uint8_t *)p)[1] = (val >> 8) & 0xff;
+ ((uint8_t *)p)[2] = val & 0xff;
+}
+
+static inline void sg_put_unaligned_be32(uint32_t val, void *p)
+{
+ __put_unaligned_be32(val, (uint8_t *)p);
+}
+
+static inline void sg_put_unaligned_be64(uint64_t val, void *p)
+{
+ __put_unaligned_be64(val, (uint8_t *)p);
+}
+
+/* Since cdb and parameter blocks are often memset to zero before these
+ * unaligned function partially fill them, then check for a val of zero
+ * and ignore if it is with these variants. */
+static inline void sg_nz_put_unaligned_be16(uint16_t val, void *p)
+{
+ if (val)
+ __put_unaligned_be16(val, (uint8_t *)p);
+}
+
+static inline void sg_nz_put_unaligned_be24(uint32_t val, void *p)
+{
+ if (val) {
+ ((uint8_t *)p)[0] = (val >> 16) & 0xff;
+ ((uint8_t *)p)[1] = (val >> 8) & 0xff;
+ ((uint8_t *)p)[2] = val & 0xff;
+ }
+}
+
+static inline void sg_nz_put_unaligned_be32(uint32_t val, void *p)
+{
+ if (val)
+ __put_unaligned_be32(val, (uint8_t *)p);
+}
+
+static inline void sg_nz_put_unaligned_be64(uint64_t val, void *p)
+{
+ if (val)
+ __put_unaligned_be64(val, (uint8_t *)p);
+}
+
+#endif /* SG_UNALIGNED_H */
diff --git a/src/sg_scan.c.win32 b/src/sg_scan.c.win32
index 38181b65..faaa7ce4 100644
--- a/src/sg_scan.c.win32
+++ b/src/sg_scan.c.win32
@@ -37,7 +37,7 @@
#include "sg_pt_win32.h"
-static const char * version_str = "1.14 (win32) 20140807";
+static const char * version_str = "1.15 (win32) 20140827";
#define MAX_SCSI_ELEMS 1024
#define MAX_ADAPTER_NUM 64
@@ -280,14 +280,15 @@ query_dev_property(HANDLE hdevice,
if (verbose > 2) {
err = GetLastError();
fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(Devprop) failed, "
- "Error=%ld %s\n", err, get_err_str(err, sizeof(b), b));
+ "Error=%u %s\n", (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
}
return -ENOSYS;
}
if (verbose > 3)
fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevProp) "
- "num_out=%ld\n", num_out);
+ "num_out=%u\n", (unsigned int)num_out);
return 0;
}
@@ -307,11 +308,11 @@ query_dev_uid(HANDLE hdevice, union STORAGE_DEVICE_UID_DATA * data)
if (verbose > 2) {
err = GetLastError();
fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid(exists)) "
- "failed, Error=%ld %s\n", err,
+ "failed, Error=%u %s\n", (unsigned int)err,
get_err_str(err, sizeof(b), b));
}
if (verbose > 3)
- fprintf(stderr, " num_out=%ld\n", num_out);
+ fprintf(stderr, " num_out=%u\n", (unsigned int)num_out);
/* interpret any error to mean this property doesn't exist */
return 0;
}
@@ -323,13 +324,14 @@ query_dev_uid(HANDLE hdevice, union STORAGE_DEVICE_UID_DATA * data)
if (verbose > 2) {
err = GetLastError();
fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid) failed, "
- "Error=%ld %s\n", err, get_err_str(err, sizeof(b), b));
+ "Error=%u %s\n", (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
}
return -ENOSYS;
}
if (verbose > 3)
- fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid) num_out=%ld\n",
- num_out);
+ fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid) num_out=%u\n",
+ (unsigned int)num_out);
return 0;
}
@@ -429,8 +431,8 @@ enum_scsi_adapters(void)
} else {
err = GetLastError();
fprintf(stderr, "%s: IOCTL_SCSI_GET_INQUIRY_DATA failed "
- "err=%lu\n\t%s",
- adapter_name, err, get_err_str(err, sizeof(b), b));
+ "err=%u\n\t%s", adapter_name, (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
}
CloseHandle(fh);
} else {
@@ -439,8 +441,9 @@ enum_scsi_adapters(void)
fprintf(stderr, "%s: in use by other process (sharing "
"violation [34])\n", adapter_name);
else if (verbose > 3)
- fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s",
- adapter_name, err, get_err_str(err, sizeof(b), b));
+ fprintf(stderr, "%s: CreateFile failed err=%u\n\t%s",
+ adapter_name, (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
if (++hole_count >= MAX_HOLE_COUNT)
break;
}
@@ -527,8 +530,9 @@ enum_pds(void)
fprintf(stderr, "%s: in use by other process (sharing "
"violation [34])\n", adapter_name);
else if (verbose > 3)
- fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s",
- adapter_name, err, get_err_str(err, sizeof(b), b));
+ fprintf(stderr, "%s: CreateFile failed err=%u\n\t%s",
+ adapter_name, (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
if (++hole_count >= MAX_HOLE_COUNT)
break;
}
@@ -577,8 +581,9 @@ enum_cdroms(void)
fprintf(stderr, "%s: in use by other process (sharing "
"violation [34])\n", adapter_name);
else if (verbose > 3)
- fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s",
- adapter_name, err, get_err_str(err, sizeof(b), b));
+ fprintf(stderr, "%s: CreateFile failed err=%u\n\t%s",
+ adapter_name, (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
if (++hole_count >= MAX_HOLE_COUNT)
break;
}
@@ -627,8 +632,9 @@ enum_tapes(void)
fprintf(stderr, "%s: in use by other process (sharing "
"violation [34])\n", adapter_name);
else if (verbose > 3)
- fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s",
- adapter_name, err, get_err_str(err, sizeof(b), b));
+ fprintf(stderr, "%s: CreateFile failed err=%u\n\t%s",
+ adapter_name, (unsigned int)err,
+ get_err_str(err, sizeof(b), b));
if (++hole_count >= MAX_HOLE_COUNT)
break;
}