switch usage of unaligned.h to sg_unaligned.h

git-svn-id: http://svn.code.sf.net/p/smartmontools/code/trunk@4727 4ea69e1a-61f1-4043-bf83-b5c94c648137
pull/15/head
dpgilbert 5 years ago
parent 7b6ce6a1be
commit cfd95aa351
  1. 18
      smartmontools/ChangeLog
  2. 4
      smartmontools/Makefile.am
  3. 5
      smartmontools/configure.ac
  4. 6
      smartmontools/json.cpp
  5. 10
      smartmontools/nvmeprint.cpp
  6. 10
      smartmontools/scsiata.cpp
  7. 102
      smartmontools/scsicmds.cpp
  8. 122
      smartmontools/scsiprint.cpp
  9. 489
      smartmontools/sg_unaligned.h
  10. 295
      smartmontools/unaligned.h

@ -1,5 +1,23 @@
$Id$
2018-04-16 Douglas Franke <dgilbert@interlog.com>
switch usage of unaligned.h to sg_unaligned.h which are functionally
the same. sg_unaligned.h is the same header used by libsgutils which
is the basis of the sg3_utils, sdparm and ddpt packages available on
many of the same architectures as smartmontools is. This change
introduces a "sg_" prefix on the inline functions defined
sg_unaligned.h . The new header has specializations for big and little
endian machines that depends on the non-standard bswap_16(), bswap_32()
and bswap_64() calls that are defined in the byteswap.h header which is
a GNU extension. According to the 'net both gcc and clang use intrinsics
{assembler ?} to implement these calls. If the byteswap.h header is not
present on the build machine, the generic implementations will be
used for the "unaligned" family of functions. Additionally the generic
implementations can be imposed with './configure --disable-fast-lebe'.
Developers may need to use './autogen.sh' prior to their normal build
sequence. Please report any problems to the author.
2018-03-28 Christian Franke <franke@computer.org>
ataprint.cpp, nvmeprint.cpp, scsiprint.cpp:

@ -85,7 +85,7 @@ smartctl_SOURCES = \
scsiprint.h \
utility.cpp \
utility.h \
unaligned.h
sg_unaligned.h
smartctl_LDADD = $(os_deps) $(os_libs)
smartctl_DEPENDENCIES = $(os_deps)
@ -152,7 +152,7 @@ smartd_SOURCES = \
scsiata.cpp \
utility.cpp \
utility.h \
unaligned.h
sg_unaligned.h
smartd_LDADD = $(os_deps) $(os_libs) $(CAPNG_LDADD)
smartd_DEPENDENCIES = $(os_deps)

@ -85,6 +85,7 @@ AC_MSG_RESULT([$is_svn_build])
dnl Checks for header files.
AC_CHECK_HEADERS([locale.h])
AC_CHECK_HEADERS([byteswap.h], [], [], [])
case "$host" in
*-*-freebsd*|*-*-dragonfly*|*-*-kfreebsd*-gnu*)
@ -319,6 +320,10 @@ AC_ARG_ENABLE([scsi-cdb-check],
AC_DEFINE_UNQUOTED(SCSI_CDB_CHECK, 1, [enable check on SCSI cdbs], )
)
AC_ARG_ENABLE([fast-lebe],
AC_HELP_STRING([--disable-fast-lebe], [use generic little-endian/big-endian code instead]),
[AC_DEFINE_UNQUOTED(IGNORE_FAST_LEBE, 1, [use generic little-endian/big-endian instead], )], [])
AC_ARG_WITH(os-deps,
[AS_HELP_STRING([--with-os-deps='os_module.o ...'], [Specify OS dependent module(s) [guessed]])],
[ for x in $with_os_deps; do

@ -21,7 +21,7 @@
const char * json_cvsid = "$Id$"
JSON_H_CVSID;
#include "unaligned.h"
#include "sg_unaligned.h"
#include <stdexcept>
@ -162,8 +162,8 @@ void json::ref::set_unsafe_uint128(uint64_t value_hi, uint64_t value_lo)
void json::ref::set_unsafe_le128(const void * pvalue)
{
set_unsafe_uint128(get_unaligned_le64((const uint8_t *)pvalue + 8),
get_unaligned_le64( pvalue ));
set_unsafe_uint128(sg_get_unaligned_le64((const uint8_t *)pvalue + 8),
sg_get_unaligned_le64( pvalue ));
}
json::node::node()

@ -28,7 +28,7 @@ const char * nvmeprint_cvsid = "$Id$"
#include "atacmds.h" // dont_print_serial_number
#include "scsicmds.h" // dStrHex()
#include "smartctl.h"
#include "unaligned.h"
#include "sg_unaligned.h"
using namespace smartmontools;
@ -133,7 +133,7 @@ static void print_drive_info(const nvme_id_ctrl & id_ctrl, const nvme_id_ns & id
jout("IEEE OUI Identifier: 0x%02x%02x%02x\n",
id_ctrl.ieee[2], id_ctrl.ieee[1], id_ctrl.ieee[0]);
jglb["nvme_ieee_oui_identifier"] = get_unaligned_le(3, id_ctrl.ieee);
jglb["nvme_ieee_oui_identifier"] = sg_get_unaligned_le(3, id_ctrl.ieee);
// Capacity info is optional for devices without namespace management
if (show_all || le128_is_non_zero(id_ctrl.tnvmcap) || le128_is_non_zero(id_ctrl.unvmcap)) {
@ -186,8 +186,8 @@ static void print_drive_info(const nvme_id_ctrl & id_ctrl, const nvme_id_ns & id
jout("Namespace %u IEEE EUI-64: %s%02x%02x%02x %02x%02x%02x%02x%02x\n",
nsid, align, id_ns.eui64[0], id_ns.eui64[1], id_ns.eui64[2], id_ns.eui64[3],
id_ns.eui64[4], id_ns.eui64[5], id_ns.eui64[6], id_ns.eui64[7]);
jrns["eui64"]["oui"] = get_unaligned_be(3, id_ns.eui64);
jrns["eui64"]["ext_id"] = get_unaligned_be(5, id_ns.eui64 + 3);
jrns["eui64"]["oui"] = sg_get_unaligned_be(3, id_ns.eui64);
jrns["eui64"]["ext_id"] = sg_get_unaligned_be(5, id_ns.eui64 + 3);
}
}
@ -341,7 +341,7 @@ static void print_smart_log(const nvme_smart_log & smart_log, unsigned nsid,
jout("Critical Warning: 0x%02x\n", smart_log.critical_warning);
jref["critical_warning"] = smart_log.critical_warning;
int k = get_unaligned_le16(smart_log.temperature);
int k = sg_get_unaligned_le16(smart_log.temperature);
jout("Temperature: %s\n", kelvin_to_str(buf, k));
if (k) {
jref["temperature"] = k - 273;

@ -61,7 +61,7 @@
#include "dev_interface.h"
#include "dev_ata_cmd_set.h" // ata_device_with_command_set
#include "dev_tunnelled.h" // tunnelled_device<>
#include "unaligned.h"
#include "sg_unaligned.h"
const char * scsiata_cpp_cvsid = "$Id$";
@ -1080,7 +1080,7 @@ bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & ou
cdb[ 0] = 0xdf;
cdb[ 1] = (rwbit ? 0x10 : 0x00);
cdb[ 2] = 0x00;
put_unaligned_be16(io_hdr.dxfer_len, cdb + 3);
sg_put_unaligned_be16(io_hdr.dxfer_len, cdb + 3);
cdb[ 5] = in.in_regs.features;
cdb[ 6] = in.in_regs.sector_count;
cdb[ 7] = in.in_regs.lba_low;
@ -1151,9 +1151,9 @@ bool usbjmicron_device::get_registers(unsigned short addr,
cdb[ 0] = 0xdf;
cdb[ 1] = 0x10;
cdb[ 2] = 0x00;
put_unaligned_be16(size, cdb + 3);
sg_put_unaligned_be16(size, cdb + 3);
cdb[ 5] = 0x00;
put_unaligned_be16(addr, cdb + 6);
sg_put_unaligned_be16(addr, cdb + 6);
cdb[ 8] = 0x00;
cdb[ 9] = 0x00;
cdb[10] = 0x00;
@ -1265,7 +1265,7 @@ bool usbprolific_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & o
cdb[ 3] = in.in_regs.features; // Feature register (SMART command)
cdb[ 4] = 0x06; // Check Word (VendorID magic, Prolific: 0x067B)
cdb[ 5] = 0x7B; // Check Word (VendorID magic, Prolific: 0x067B)
put_unaligned_be32(io_hdr.dxfer_len, cdb + 6);
sg_put_unaligned_be32(io_hdr.dxfer_len, cdb + 6);
cdb[10] = in.in_regs.sector_count; // Sector Count
cdb[11] = in.in_regs.lba_low; // LBA Low (7:0)
cdb[12] = in.in_regs.lba_mid; // LBA Mid (15:8)

@ -46,7 +46,7 @@
#include "atacmds.h" // FIXME: for smart_command_set only
#include "dev_interface.h"
#include "utility.h"
#include "unaligned.h"
#include "sg_unaligned.h"
const char *scsicmds_c_cvsid="$Id$"
SCSICMDS_H_CVSID;
@ -65,7 +65,7 @@ supported_vpd_pages::supported_vpd_pages(scsi_device * device) : num_valid(0)
memset(b, 0, sizeof(b));
if (device && (0 == scsiInquiryVpd(device, SCSI_VPD_SUPPORTED_VPD_PAGES,
b, sizeof(b)))) {
num_valid = get_unaligned_be16(b + 2);
num_valid = sg_get_unaligned_be16(b + 2);
int n = sizeof(pages);
if (num_valid > n)
num_valid = n;
@ -175,11 +175,11 @@ is_scsi_cdb(const uint8_t * cdbp, int clen)
return false; /* must be modulo 4 and 12 or more bytes */
switch (opcode) {
case 0x7e: /* Extended cdb (XCDB) */
ilen = 4 + get_unaligned_be16(cdbp + 2);
ilen = 4 + sg_get_unaligned_be16(cdbp + 2);
return (ilen == clen);
case 0x7f: /* Variable Length cdb */
ilen = 8 + cdbp[7];
sa = get_unaligned_be16(cdbp + 8);
sa = sg_get_unaligned_be16(cdbp + 8);
/* service action (sa) 0x0 is reserved */
return ((ilen == clen) && sa);
default:
@ -552,7 +552,7 @@ scsiLogSense(scsi_device * device, int pagenum, int subpagenum, uint8_t *pBuf,
cdb[0] = LOG_SENSE;
cdb[2] = 0x40 | (pagenum & 0x3f); /* Page control (PC)==1 */
cdb[3] = subpagenum; /* 0 for no sub-page */
put_unaligned_be16(pageLen, cdb + 7);
sg_put_unaligned_be16(pageLen, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -568,7 +568,7 @@ scsiLogSense(scsi_device * device, int pagenum, int subpagenum, uint8_t *pBuf,
/* sanity check on response */
if ((SUPPORTED_LPAGES != pagenum) && ((pBuf[0] & 0x3f) != pagenum))
return SIMPLE_ERR_BAD_RESP;
uint16_t u = get_unaligned_be16(pBuf + 2);
uint16_t u = sg_get_unaligned_be16(pBuf + 2);
if (0 == u)
return SIMPLE_ERR_BAD_RESP;
pageLen = u + 4;
@ -589,7 +589,7 @@ scsiLogSense(scsi_device * device, int pagenum, int subpagenum, uint8_t *pBuf,
cdb[0] = LOG_SENSE;
cdb[2] = 0x40 | (pagenum & 0x3f); /* Page control (PC)==1 */
cdb[3] = subpagenum;
put_unaligned_be16(pageLen, cdb + 7);
sg_put_unaligned_be16(pageLen, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -605,7 +605,7 @@ scsiLogSense(scsi_device * device, int pagenum, int subpagenum, uint8_t *pBuf,
/* sanity check on response */
if ((SUPPORTED_LPAGES != pagenum) && ((pBuf[0] & 0x3f) != pagenum))
return SIMPLE_ERR_BAD_RESP;
if (0 == get_unaligned_be16(pBuf + 2))
if (0 == sg_get_unaligned_be16(pBuf + 2))
return SIMPLE_ERR_BAD_RESP;
return 0;
}
@ -633,7 +633,7 @@ scsiLogSelect(scsi_device * device, int pcr, int sp, int pc, int pagenum,
cdb[1] = (pcr ? 2 : 0) | (sp ? 1 : 0);
cdb[2] = ((pc << 6) & 0xc0) | (pagenum & 0x3f);
cdb[3] = (subpagenum & 0xff);
put_unaligned_be16(bufLen, cdb + 7);
sg_put_unaligned_be16(bufLen, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -764,7 +764,7 @@ scsiModeSense10(scsi_device * device, int pagenum, int subpagenum, int pc,
cdb[0] = MODE_SENSE_10;
cdb[2] = (pc << 6) | (pagenum & 0x3f);
cdb[3] = subpagenum;
put_unaligned_be16(bufLen, cdb + 7);
sg_put_unaligned_be16(bufLen, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -809,7 +809,7 @@ scsiModeSelect10(scsi_device * device, int sp, uint8_t *pBuf, int bufLen)
uint8_t sense[32];
int pg_offset, pg_len, hdr_plus_1_pg;
pg_offset = 8 + get_unaligned_be16(pBuf + 6);
pg_offset = 8 + sg_get_unaligned_be16(pBuf + 6);
if (pg_offset + 2 >= bufLen)
return -EINVAL;
pg_len = pBuf[pg_offset + 1] + 2;
@ -827,7 +827,7 @@ scsiModeSelect10(scsi_device * device, int sp, uint8_t *pBuf, int bufLen)
cdb[0] = MODE_SELECT_10;
cdb[1] = 0x10 | (sp & 1); /* set PF (page format) bit always */
/* make sure only one page sent */
put_unaligned_be16(hdr_plus_1_pg, cdb + 7);
sg_put_unaligned_be16(hdr_plus_1_pg, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -859,7 +859,7 @@ scsiStdInquiry(scsi_device * device, uint8_t *pBuf, int bufLen)
io_hdr.dxfer_len = bufLen;
io_hdr.dxferp = pBuf;
cdb[0] = INQUIRY;
put_unaligned_be16(bufLen, cdb + 3);
sg_put_unaligned_be16(bufLen, cdb + 3);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -904,7 +904,7 @@ try_again:
cdb[0] = INQUIRY;
cdb[1] = 0x1; /* set EVPD bit (enable Vital Product Data) */
cdb[2] = vpd_page;
put_unaligned_be16(bufLen, cdb + 3);
sg_put_unaligned_be16(bufLen, cdb + 3);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -986,7 +986,7 @@ scsiRequestSense(scsi_device * device, struct scsi_sense_disect * sense_info)
break;
}
if (buff[15] & 0x80) { /* SKSV bit set */
sense_info->progress = get_unaligned_be16(buff + 16);
sense_info->progress = sg_get_unaligned_be16(buff + 16);
break;
} else {
break;
@ -998,11 +998,11 @@ scsiRequestSense(scsi_device * device, struct scsi_sense_disect * sense_info)
sk_pr = (SCSI_SK_NO_SENSE == sk) || (SCSI_SK_NOT_READY == sk);
if (sk_pr && ((ucp = sg_scsi_sense_desc_find(buff, sz_buff, 2))) &&
(0x6 == ucp[1]) && (0x80 & ucp[4])) {
sense_info->progress = get_unaligned_be16(ucp + 5);
sense_info->progress = sg_get_unaligned_be16(ucp + 5);
break;
} else if (((ucp = sg_scsi_sense_desc_find(buff, sz_buff, 0xa))) &&
((0x6 == ucp[1]))) {
sense_info->progress = get_unaligned_be16(ucp + 6);
sense_info->progress = sg_get_unaligned_be16(ucp + 6);
break;
} else
break;
@ -1037,7 +1037,7 @@ scsiSendDiagnostic(scsi_device * device, int functioncode, uint8_t *pBuf,
cdb[1] = (functioncode & 0x7) << 5; /* SelfTest _code_ */
else /* SCSI_DIAG_NO_SELF_TEST == functioncode */
cdb[1] = 0x10; /* PF bit */
put_unaligned_be16(bufLen, cdb + 3);
sg_put_unaligned_be16(bufLen, cdb + 3);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -1120,7 +1120,7 @@ scsiReadDefect10(scsi_device * device, int req_plist, int req_glist,
cdb[0] = READ_DEFECT_10;
cdb[2] = (unsigned char)(((req_plist << 4) & 0x10) |
((req_glist << 3) & 0x8) | (dl_format & 0x7));
put_unaligned_be16(bufLen, cdb + 7);
sg_put_unaligned_be16(bufLen, cdb + 7);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -1157,8 +1157,8 @@ scsiReadDefect12(scsi_device * device, int req_plist, int req_glist,
cdb[0] = READ_DEFECT_12;
cdb[1] = (unsigned char)(((req_plist << 4) & 0x10) |
((req_glist << 3) & 0x8) | (dl_format & 0x7));
put_unaligned_be32(addrDescIndex, cdb + 2);
put_unaligned_be32(bufLen, cdb + 6);
sg_put_unaligned_be32(addrDescIndex, cdb + 2);
sg_put_unaligned_be32(bufLen, cdb + 6);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -1208,9 +1208,9 @@ scsiReadCapacity10(scsi_device * device, unsigned int * last_lbap,
if (res)
return res;
if (last_lbap)
*last_lbap = get_unaligned_be32(resp + 0);
*last_lbap = sg_get_unaligned_be32(resp + 0);
if (lb_sizep)
*lb_sizep = get_unaligned_be32(resp + 4);
*lb_sizep = sg_get_unaligned_be32(resp + 4);
return 0;
}
@ -1232,7 +1232,7 @@ scsiReadCapacity16(scsi_device * device, uint8_t *pBuf, int bufLen)
io_hdr.dxferp = pBuf;
cdb[0] = READ_CAPACITY_16;
cdb[1] = SAI_READ_CAPACITY_16;
put_unaligned_be32(bufLen, cdb + 10);
sg_put_unaligned_be32(bufLen, cdb + 10);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
@ -1294,8 +1294,8 @@ scsiGetSize(scsi_device * device, bool avoid_rcap16,
bool prot_en;
uint8_t p_type;
ret_val = get_unaligned_be64(rc16resp + 0) + 1;
lb_size = get_unaligned_be32(rc16resp + 8);
ret_val = sg_get_unaligned_be64(rc16resp + 0) + 1;
lb_size = sg_get_unaligned_be32(rc16resp + 8);
if (srrp) { /* writes to all fields */
srrp->num_lblocks = ret_val;
srrp->lb_size = lb_size;
@ -1306,7 +1306,7 @@ scsiGetSize(scsi_device * device, bool avoid_rcap16,
srrp->lb_p_pb_exp = (rc16resp[13] & 0xf);
srrp->lbpme = !!(0x80 & rc16resp[14]);
srrp->lbprz = !!(0x40 & rc16resp[14]);
srrp->l_a_lba = get_unaligned_be16(rc16resp + 14) & 0x3fff;
srrp->l_a_lba = sg_get_unaligned_be16(rc16resp + 14) & 0x3fff;
}
}
}
@ -1339,8 +1339,8 @@ scsiModePageOffset(const uint8_t * resp, int len, int modese_len)
if (resp) {
int resp_len, bd_len;
if (10 == modese_len) {
resp_len = get_unaligned_be16(resp + 0) + 2;
bd_len = get_unaligned_be16(resp + 6);
resp_len = sg_get_unaligned_be16(resp + 0) + 2;
bd_len = sg_get_unaligned_be16(resp + 6);
offset = bd_len + 8;
} else {
resp_len = resp[0] + 1;
@ -1481,7 +1481,7 @@ scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == iecp->modese_len) {
resp_len = get_unaligned_be16(rout + 0) + 2;
resp_len = sg_get_unaligned_be16(rout + 0) + 2;
rout[3] &= 0xef;
} else {
resp_len = rout[0] + 1;
@ -1493,8 +1493,8 @@ scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
if (scsi_debugmode > 2)
rout[offset + 2] |= SCSI_IEC_MP_BYTE2_TEST_MASK;
rout[offset + 3] = SCSI_IEC_MP_MRIE;
put_unaligned_be32(SCSI_IEC_MP_INTERVAL_T, rout + offset + 4);
put_unaligned_be32(SCSI_IEC_MP_REPORT_COUNT, rout + offset + 8);
sg_put_unaligned_be32(SCSI_IEC_MP_INTERVAL_T, rout + offset + 4);
sg_put_unaligned_be32(SCSI_IEC_MP_REPORT_COUNT, rout + offset + 8);
if (iecp->gotChangeable) {
uint8_t chg2 = iecp->raw_chg[offset + 2];
@ -1581,7 +1581,7 @@ scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage,
return err;
}
// pull out page size from response, don't forget to add 4
unsigned short pagesize = get_unaligned_be16(tBuf + 2) + 4;
unsigned short pagesize = sg_get_unaligned_be16(tBuf + 2) + 4;
if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
pout("%s failed, IE page, bad parameter code or length\n",
logSenStr);
@ -2274,7 +2274,7 @@ scsiFetchExtendedSelfTestTime(scsi_device * device, int * durationSec,
if (offset < 0)
return -EINVAL;
if (buff[offset + 1] >= 0xa) {
int res = get_unaligned_be16(buff + offset + 10);
int res = sg_get_unaligned_be16(buff + offset + 10);
*durationSec = res;
return 0;
}
@ -2286,10 +2286,10 @@ void
scsiDecodeErrCounterPage(unsigned char * resp, struct scsiErrorCounter *ecp)
{
memset(ecp, 0, sizeof(*ecp));
int num = get_unaligned_be16(resp + 2);
int num = sg_get_unaligned_be16(resp + 2);
unsigned char * ucp = &resp[0] + 4;
while (num > 3) {
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
int pl = ucp[3] + 4;
uint64_t * ullp;
switch (pc) {
@ -2314,7 +2314,7 @@ scsiDecodeErrCounterPage(unsigned char * resp, struct scsiErrorCounter *ecp)
xp += (k - sizeof(*ullp));
k = sizeof(*ullp);
}
*ullp = get_unaligned_be(k, xp);
*ullp = sg_get_unaligned_be(k, xp);
num -= pl;
ucp += pl;
}
@ -2325,11 +2325,11 @@ scsiDecodeNonMediumErrPage(unsigned char *resp,
struct scsiNonMediumError *nmep)
{
memset(nmep, 0, sizeof(*nmep));
int num = get_unaligned_be16(resp + 2);
int num = sg_get_unaligned_be16(resp + 2);
unsigned char * ucp = &resp[0] + 4;
int szof = sizeof(nmep->counterPC0);
while (num > 3) {
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
int pl = ucp[3] + 4;
int k;
unsigned char * xp;
@ -2342,7 +2342,7 @@ scsiDecodeNonMediumErrPage(unsigned char *resp,
xp += (k - szof);
k = szof;
}
nmep->counterPC0 = get_unaligned_be(k, xp + 0);
nmep->counterPC0 = sg_get_unaligned_be(k, xp + 0);
break;
case 0x8009:
nmep->gotTFE_H = 1;
@ -2352,7 +2352,7 @@ scsiDecodeNonMediumErrPage(unsigned char *resp,
xp += (k - szof);
k = szof;
}
nmep->counterTFE_H = get_unaligned_be(k, xp + 0);
nmep->counterTFE_H = sg_get_unaligned_be(k, xp + 0);
break;
case 0x8015:
nmep->gotPE_H = 1;
@ -2362,7 +2362,7 @@ scsiDecodeNonMediumErrPage(unsigned char *resp,
xp += (k - szof);
k = szof;
}
nmep->counterPE_H = get_unaligned_be(k, xp + 0);
nmep->counterPE_H = sg_get_unaligned_be(k, xp + 0);
break;
default:
nmep->gotExtraPC = 1;
@ -2400,7 +2400,7 @@ scsiCountFailedSelfTests(scsi_device * fd, int noisy)
return -1;
}
// compute page length
num = get_unaligned_be16(resp + 2);
num = sg_get_unaligned_be16(resp + 2);
// Log sense page length 0x190 bytes
if (num != 0x190) {
if (noisy)
@ -2414,7 +2414,7 @@ scsiCountFailedSelfTests(scsi_device * fd, int noisy)
for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
// timestamp in power-on hours (or zero if test in progress)
int n = get_unaligned_be16(ucp + 6);
int n = sg_get_unaligned_be16(ucp + 6);
// The spec says "all 20 bytes will be zero if no test" but
// DG has found otherwise. So this is a heuristic.
@ -2424,7 +2424,7 @@ scsiCountFailedSelfTests(scsi_device * fd, int noisy)
if ((res > 2) && (res < 8)) {
fails++;
if (1 == fails)
fail_hour = get_unaligned_be16(ucp + 6);
fail_hour = sg_get_unaligned_be16(ucp + 6);
}
}
return (fail_hour << 8) + fails;
@ -2445,7 +2445,7 @@ scsiSelfTestInProgress(scsi_device * fd, int * inProgress)
if (resp[0] != SELFTEST_RESULTS_LPAGE)
return -1;
// compute page length
num = get_unaligned_be16(resp + 2);
num = sg_get_unaligned_be16(resp + 2);
// Log sense page length 0x190 bytes
if (num != 0x190) {
return -1;
@ -2506,8 +2506,8 @@ scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
memset(buff, 0, sizeof(buff));
if ((0 == scsiInquiryVpd(device, SCSI_VPD_BLOCK_DEVICE_CHARACTERISTICS,
buff, sizeof(buff))) &&
((get_unaligned_be16(buff + 2)) > 2)) {
int speed = get_unaligned_be16(buff + 4);
((sg_get_unaligned_be16(buff + 2)) > 2)) {
int speed = sg_get_unaligned_be16(buff + 4);
if (form_factorp)
*form_factorp = buff[7] & 0xf;
if (haw_zbcp)
@ -2535,7 +2535,7 @@ scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
return -EINVAL;
}
offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
return get_unaligned_be16(buff + offset + 20);
return sg_get_unaligned_be16(buff + offset + 20);
}
/* Returns a non-zero value in case of error, wcep/rcdp == -1 - get value,
@ -2624,7 +2624,7 @@ scsiGetSetCache(scsi_device * device, int modese_len, short int * wcep,
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == modese_len) {
resp_len = get_unaligned_be16(buff + 0) + 2;
resp_len = sg_get_unaligned_be16(buff + 0) + 2;
buff[3] &= 0xef;
} else {
resp_len = buff[0] + 1;
@ -2695,7 +2695,7 @@ scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len)
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == modese_len) {
resp_len = get_unaligned_be16(buff + 0) + 2;
resp_len = sg_get_unaligned_be16(buff + 0) + 2;
buff[3] &= 0xef;
} else {
resp_len = buff[0] + 1;

@ -37,7 +37,7 @@
#include "scsiprint.h"
#include "smartctl.h"
#include "utility.h"
#include "unaligned.h"
#include "sg_unaligned.h"
#define GBUF_SIZE 65532
@ -100,7 +100,8 @@ static const char * logSenStr = "Log Sense";
static const char * logSenRspStr = "Log Sense response";
static bool seagate_or_hitachi(void)
static bool
seagate_or_hitachi(void)
{
return ((0 == memcmp(scsi_vendor, T10_VENDOR_SEAGATE,
strlen(T10_VENDOR_SEAGATE))) ||
@ -112,6 +113,18 @@ static bool seagate_or_hitachi(void)
strlen(T10_VENDOR_HITACHI_3))));
}
static bool
all_ffs(const uint8_t * bp, int b_len)
{
if ((NULL == bp) || (b_len <= 0))
return false;
for (--b_len; b_len >= 0; --b_len) {
if (0xff != bp[b_len])
return false;
}
return true;
}
static void
scsiGetSupportedLogPages(scsi_device * device)
{
@ -163,7 +176,7 @@ scsiGetSupportedLogPages(scsi_device * device)
memcpy(sup_lpgs, gBuf, LOG_RESP_LEN);
if (got_subpages) {
payload_len = get_unaligned_be16(gBuf + 2);
payload_len = sg_get_unaligned_be16(gBuf + 2);
bump = 2;
up = gBuf + LOGPAGEHDRSIZE;
} else {
@ -364,11 +377,11 @@ scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
print_off();
return -1;
}
pagelength = get_unaligned_be16(gBuf + 2);
pagelength = sg_get_unaligned_be16(gBuf + 2);
for (s=severities; *s; s++) {
for (i = 4; i < pagelength; i += 5) {
parametercode = get_unaligned_be16(gBuf + i);
parametercode = sg_get_unaligned_be16(gBuf + i);
if (gBuf[i + 4]) {
ts = SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
@ -411,7 +424,7 @@ scsiGetStartStopData(scsi_device * device)
print_off();
return;
}
len = get_unaligned_be16(gBuf + 2);
len = sg_get_unaligned_be16(gBuf + 2);
ucp = gBuf + 4;
for (k = len; k > 0; k -= extra, ucp += extra) {
if (k < 3) {
@ -421,8 +434,8 @@ scsiGetStartStopData(scsi_device * device)
return;
}
extra = ucp[3] + 4;
int pc = get_unaligned_be16(ucp + 0);
uint32_t u = (extra > 7) ? get_unaligned_be32(ucp + 4) : 0;
int pc = sg_get_unaligned_be16(ucp + 0);
uint32_t u = (extra > 7) ? sg_get_unaligned_be32(ucp + 4) : 0;
bool is_all_ffs = (extra > 7) ? all_ffs(ucp + 4, 4) : false;
switch (pc) {
case 1:
@ -481,7 +494,7 @@ scsiPrintPendingDefectsLPage(scsi_device * device)
print_off();
return;
}
num = get_unaligned_be16(gBuf + 2);
num = sg_get_unaligned_be16(gBuf + 2);
if (num > LOG_RESP_LONG_LEN) {
print_on();
pout("%s %s too long\n", pDefStr, logSenRspStr);
@ -490,7 +503,7 @@ scsiPrintPendingDefectsLPage(scsi_device * device)
}
bp = gBuf + 4;
while (num > 3) {
pc = get_unaligned_be16(bp + 0);
pc = sg_get_unaligned_be16(bp + 0);
pl = bp[3] + 4;
switch (pc) {
case 0x0:
@ -501,7 +514,7 @@ scsiPrintPendingDefectsLPage(scsi_device * device)
print_off();
return;
}
count = get_unaligned_be32(bp + 4);
count = sg_get_unaligned_be32(bp + 4);
jglb[jname]["count"] = count;
if (0 == count)
jout("0 %s\n", pDefStr);
@ -520,10 +533,10 @@ scsiPrintPendingDefectsLPage(scsi_device * device)
return;
}
jout(" %4d: 0x%-16" PRIx64 ", %5u\n", pc,
get_unaligned_be64(bp + 8), get_unaligned_be32(bp + 4));
jglb[jname][pc]["LBA"] = get_unaligned_be64(bp + 8);
sg_get_unaligned_be64(bp + 8), sg_get_unaligned_be32(bp + 4));
jglb[jname][pc]["LBA"] = sg_get_unaligned_be64(bp + 8);
jglb[jname][pc]["accum_power_on_hours"] =
get_unaligned_be32(bp + 4);
sg_get_unaligned_be32(bp + 4);
break;
}
num -= pl;
@ -570,15 +583,15 @@ scsiPrintGrownDefectListLen(scsi_device * device)
got_rd12 = true;
if (got_rd12) {
int generation = get_unaligned_be16(gBuf + 2);
int generation = sg_get_unaligned_be16(gBuf + 2);
if ((generation > 1) && (scsi_debugmode > 0)) {
print_on();
pout("%s (12): generation=%d\n", hname, generation);
print_off();
}
dl_len = get_unaligned_be32(gBuf + 4);
dl_len = sg_get_unaligned_be32(gBuf + 4);
} else
dl_len = get_unaligned_be16(gBuf + 2);
dl_len = sg_get_unaligned_be16(gBuf + 2);
if (0x8 != (gBuf[1] & 0x18)) {
print_on();
pout("%s: asked for grown list but didn't get it\n", hname);
@ -644,11 +657,11 @@ scsiPrintSeagateCacheLPage(scsi_device * device)
}
return;
}
len = get_unaligned_be16(gBuf + 2) + 4;
len = sg_get_unaligned_be16(gBuf + 2) + 4;
num = len - 4;
ucp = &gBuf[0] + 4;
while (num > 3) {
pc = get_unaligned_be16(ucp + 0);
pc = sg_get_unaligned_be16(ucp + 0);
pl = ucp[3] + 4;
switch (pc) {
case 0: case 1: case 2: case 3: case 4:
@ -669,7 +682,7 @@ scsiPrintSeagateCacheLPage(scsi_device * device)
num = len - 4;
ucp = &gBuf[0] + 4;
while (num > 3) {
pc = get_unaligned_be16(ucp + 0);
pc = sg_get_unaligned_be16(ucp + 0);
pl = ucp[3] + 4;
switch (pc) {
case 0: pout(" Blocks sent to initiator"); break;
@ -688,7 +701,7 @@ scsiPrintSeagateCacheLPage(scsi_device * device)
xp += (k - sz_ull);
k = sz_ull;
}
ull = get_unaligned_be(k, xp + 0);
ull = sg_get_unaligned_be(k, xp + 0);
pout(" = %" PRIu64 "\n", ull);
num -= pl;
ucp += pl;
@ -720,13 +733,13 @@ scsiPrintSeagateFactoryLPage(scsi_device * device)
}
return;
}
len = get_unaligned_be16(gBuf + 2) + 4;
len = sg_get_unaligned_be16(gBuf + 2) + 4;
num = len - 4;
ucp = &gBuf[0] + 4;
good = 0;
bad = 0;
while (num > 3) {
pc = get_unaligned_be16(ucp + 0);
pc = sg_get_unaligned_be16(ucp + 0);
pl = ucp[3] + 4;
switch (pc) {
case 0: case 8:
@ -752,7 +765,7 @@ scsiPrintSeagateFactoryLPage(scsi_device * device)
num = len - 4;
ucp = &gBuf[0] + 4;
while (num > 3) {
pc = get_unaligned_be16(ucp + 0);
pc = sg_get_unaligned_be16(ucp + 0);
pl = ucp[3] + 4;
good = 0;
switch (pc) {
@ -778,7 +791,7 @@ scsiPrintSeagateFactoryLPage(scsi_device * device)
xp += (k - (int)sizeof(ull));
k = (int)sizeof(ull);
}
ull = get_unaligned_be(k, xp + 0);
ull = sg_get_unaligned_be(k, xp + 0);
if (0 == pc)
pout(" = %.2f\n", ull / 60.0 );
else
@ -859,7 +872,7 @@ scsiPrintErrorCounterLog(scsi_device * device)
if (gLastNErrorEvLPage &&
(0 == scsiLogSense(device, LAST_N_ERROR_EVENTS_LPAGE, 0, gBuf,
LOG_RESP_LONG_LEN, 0))) {
int num = get_unaligned_be16(gBuf + 2) + 4;
int num = sg_get_unaligned_be16(gBuf + 2) + 4;
int truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
if (truncated)
num = LOG_RESP_LONG_LEN;
@ -875,7 +888,7 @@ scsiPrintErrorCounterLog(scsi_device * device)
break;
}
pl = ucp[3] + 4;
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
if (pl > 4) {
if ((ucp[2] & 0x1) && (ucp[2] & 0x2)) {
pout(" Error event %d:\n", pc);
@ -968,7 +981,7 @@ scsiPrintSelfTest(scsi_device * device)
return FAILSMART;
}
// compute page length
num = get_unaligned_be16(gBuf + 2);
num = sg_get_unaligned_be16(gBuf + 2);
// Log sense page length 0x190 bytes
if (num != 0x190) {
print_on();
@ -979,7 +992,7 @@ scsiPrintSelfTest(scsi_device * device)
// loop through the twenty possible entries
for (k = 0, ucp = gBuf + 4; k < 20; ++k, ucp += 20 ) {
// timestamp in power-on hours (or zero if test in progress)
int n = get_unaligned_be16(ucp + 6);
int n = sg_get_unaligned_be16(ucp + 6);
// The spec says "all 20 bytes will be zero if no test" but
// DG has found otherwise. So this is a heuristic.
@ -997,7 +1010,7 @@ scsiPrintSelfTest(scsi_device * device)
}
// print parameter code (test number) & self-test code text
pout("#%2d %s", get_unaligned_be16(ucp + 0),
pout("#%2d %s", sg_get_unaligned_be16(ucp + 0),
self_test_code[(ucp[4] >> 5) & 0x7]);
// check the self-test result nibble, using the self-test results
@ -1054,7 +1067,7 @@ scsiPrintSelfTest(scsi_device * device)
pout(" %5d", n);
// construct 8-byte integer address of first failure
ull = get_unaligned_be64(ucp + 8);
ull = sg_get_unaligned_be64(ucp + 8);
bool is_all_ffs = all_ffs(ucp + 8, 8);
// print Address of First Failure, if sensible
if ((! is_all_ffs) && (res > 0) && (res < 0xf)) {
@ -1140,7 +1153,7 @@ scsiPrintBackgroundResults(scsi_device * device)
return FAILSMART;
}
// compute page length
num = get_unaligned_be16(gBuf + 2) + 4;
num = sg_get_unaligned_be16(gBuf + 2) + 4;
if (num < 20) {
print_on();
pout("%s %s length is %d, no scan status\n", hname, logSenStr, num);
@ -1153,7 +1166,7 @@ scsiPrintBackgroundResults(scsi_device * device)
ucp = gBuf + 4;
num -= 4;
while (num > 3) {
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
// pcb = ucp[2];
int pl = ucp[3] + 4;
switch (pc) {
@ -1172,15 +1185,15 @@ scsiPrintBackgroundResults(scsi_device * device)
pout("%s\n", bms_status[j]);
else
pout("unknown [0x%x] background scan status value\n", j);
j = get_unaligned_be32(ucp + 4);
j = sg_get_unaligned_be32(ucp + 4);
pout(" Accumulated power on time, hours:minutes %d:%02d "
"[%d minutes]\n", (j / 60), (j % 60), j);
pout(" Number of background scans performed: %d, ",
get_unaligned_be16(ucp + 10));
sg_get_unaligned_be16(ucp + 10));
pout("scan progress: %.2f%%\n",
(double)get_unaligned_be16(ucp + 12) * 100.0 / 65536.0);
(double)sg_get_unaligned_be16(ucp + 12) * 100.0 / 65536.0);
pout(" Number of background medium scans performed: %d\n",
get_unaligned_be16(ucp + 14));
sg_get_unaligned_be16(ucp + 14));
break;
default:
if (noheader) {
@ -1198,7 +1211,7 @@ scsiPrintBackgroundResults(scsi_device * device)
pout("parameter length >= 24 expected, got %d\n", pl);
break;
}
j = get_unaligned_be32(ucp + 4);
j = sg_get_unaligned_be32(ucp + 4);
pout("%4d:%02d ", (j / 60), (j % 60));
for (m = 0; m < 8; ++m)
pout("%02x", ucp[16 + m]);
@ -1247,7 +1260,7 @@ scsiPrintSSMedia(scsi_device * device)
return FAILSMART;
}
// compute page length
num = get_unaligned_be16(gBuf + 2) + 4;
num = sg_get_unaligned_be16(gBuf + 2) + 4;
if (num < 12) {
print_on();
pout("%s %s length is %d, too short\n", hname, logSenStr, num);
@ -1260,7 +1273,7 @@ scsiPrintSSMedia(scsi_device * device)
ucp = gBuf + 4;
num -= 4;
while (num > 3) {
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
// pcb = ucp[2];
int pl = ucp[3] + 4;
switch (pc) {
@ -1310,7 +1323,7 @@ scsiPrintFormatStatus(scsi_device * device)
return FAILSMART;
}
// compute page length
num = get_unaligned_be16(gBuf + 2) + 4;
num = sg_get_unaligned_be16(gBuf + 2) + 4;
if (num < 12) {
print_on();
jout("%s %s length is %d, too short\n", hname, logSenStr, num);
@ -1323,7 +1336,7 @@ scsiPrintFormatStatus(scsi_device * device)
ucp = gBuf + 4;
num -= 4;
while (num > 3) {
int pc = get_unaligned_be16(ucp + 0);
int pc = sg_get_unaligned_be16(ucp + 0);
// pcb = ucp[2];
int pl = ucp[3] + 4;
@ -1381,7 +1394,7 @@ scsiPrintFormatStatus(scsi_device * device)
xp += (k - sizeof(ull));
k = sizeof(ull);
}
ull = get_unaligned_be(k, xp);
ull = sg_get_unaligned_be(k, xp);
jout("%s = %" PRIu64 "\n", jout_str, ull);
jglb[jname][jglb_str] = ull;
}
@ -1533,7 +1546,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
sz = sizeof(s);
// pcb = ucp[2];
t = get_unaligned_be16(ucp + 0);
t = sg_get_unaligned_be16(ucp + 0);
pout("relative target port id = %d\n", t);
pout(" generation code = %d\n", ucp[6]);
nphys = ucp[7];
@ -1617,21 +1630,21 @@ show_sas_port_param(unsigned char * ucp, int param_len)
pout(" attached target port: ssp=%d stp=%d smp=%d\n",
!! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
if (!dont_print_serial_number) {
uint64_t ull = get_unaligned_be64(vcp + 8);
uint64_t ull = sg_get_unaligned_be64(vcp + 8);
pout(" SAS address = 0x%" PRIx64 "\n", ull);
ull = get_unaligned_be64(vcp + 16);
ull = sg_get_unaligned_be64(vcp + 16);
pout(" attached SAS address = 0x%" PRIx64 "\n", ull);
}
pout(" attached phy identifier = %d\n", vcp[24]);
unsigned int ui = get_unaligned_be32(vcp + 32);
unsigned int ui = sg_get_unaligned_be32(vcp + 32);
pout(" Invalid DWORD count = %u\n", ui);
ui = get_unaligned_be32(vcp + 36);
ui = sg_get_unaligned_be32(vcp + 36);
pout(" Running disparity error count = %u\n", ui);
ui = get_unaligned_be32(vcp + 40);
ui = sg_get_unaligned_be32(vcp + 40);
pout(" Loss of DWORD synchronization = %u\n", ui);
ui = get_unaligned_be32(vcp + 44);
ui = sg_get_unaligned_be32(vcp + 44);
pout(" Phy reset problem = %u\n", ui);
if (spld_len > 51) {
int num_ped;
@ -1645,8 +1658,8 @@ show_sas_port_param(unsigned char * ucp, int param_len)
int peis;
unsigned int pvdt;
peis = xcp[3];
ui = get_unaligned_be32(xcp + 4);
pvdt = get_unaligned_be32(xcp + 8);
ui = sg_get_unaligned_be32(xcp + 4);
pvdt = sg_get_unaligned_be32(xcp + 8);
show_sas_phy_event_info(peis, ui, pvdt);
}
}
@ -1699,7 +1712,7 @@ scsiPrintSasPhy(scsi_device * device, int reset)
return FAILSMART;
}
// compute page length
num = get_unaligned_be16(gBuf + 2);
num = sg_get_unaligned_be16(gBuf + 2);
if (1 != show_protocol_specific_page(gBuf, num + 4)) {
print_on();
pout("Only support %s log page on SAS devices\n\n", hname);
@ -1875,7 +1888,8 @@ scsiGetDriveInfo(scsi_device * device, uint8_t * peripheral_type, bool all)
format_capacity(si_str, sizeof(si_str), capacity);
jout("User Capacity: %s bytes [%s]\n", cap_str, si_str);
if (srr.lb_size)
jglb["user_capacity"]["blocks"].set_unsafe_uint64(capacity / srr.lb_size);
jglb["user_capacity"]["blocks"].set_unsafe_uint64(capacity /
srr.lb_size);
jglb["user_capacity"]["bytes"].set_unsafe_uint64(capacity);
jout("Logical block size: %u bytes\n", srr.lb_size);
jglb["logical_block_size"] = srr.lb_size;

@ -0,0 +1,489 @@
#ifndef SG_UNALIGNED_H
#define SG_UNALIGNED_H
/*
* Copyright (c) 2014-2018 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.
*/
#include <stdbool.h>
#include <stdint.h> /* for uint8_t and friends */
#include <string.h> /* for memcpy */
#ifdef __cplusplus
extern "C" {
#endif
/* These inline functions convert integers (always unsigned) to byte streams
* and vice versa. They have two goals:
* - change the byte ordering of integers between host order and big
* endian ("_be") or little endian ("_le")
* - copy the big or little endian byte stream so it complies with any
* alignment that host integers require
*
* Host integer to given endian byte stream is a "_put_" function taking
* two arguments (integer and pointer to byte stream) returning void.
* Given endian byte stream to host integer is a "_get_" function that takes
* one argument and returns an integer of appropriate size (uint32_t for 24
* bit operations, uint64_t for 48 bit operations).
*
* Big endian byte format "on the wire" is the default used by SCSI
* standards (www.t10.org). Big endian is also the network byte order.
* Little endian is used by ATA, PCI and NVMe.
*/
/* The generic form of these routines was borrowed from the Linux kernel,
* via mhvtl. There is a specialised version of the main functions for
* little endian or big endian provided that not-quite-standard defines for
* endianness are available from the compiler and the <byteswap.h> header
* (a GNU extension) has been detected by ./configure . To force the
* generic version, use './configure --disable-fast-lebe ' . */
/* Note: Assumes that the source and destination locations do not overlap.
* An example of overlapping source and destination:
* sg_put_unaligned_le64(j, ((uint8_t *)&j) + 1);
* Best not to do things like that.
*/
#ifdef HAVE_CONFIG_H
#include "config.h" /* need this to see if HAVE_BYTESWAP_H */
#endif
#undef GOT_UNALIGNED_SPECIALS /* just in case */
#if defined(__BYTE_ORDER__) && defined(HAVE_BYTESWAP_H) && \
! defined(IGNORE_FAST_LEBE)
#if defined(__LITTLE_ENDIAN__) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define GOT_UNALIGNED_SPECIALS 1
#include <byteswap.h> /* for bswap_16(), bswap_32() and bswap_64() */
// #warning ">>>>>> Doing Little endian special unaligneds"
static inline uint16_t sg_get_unaligned_be16(const void *p)
{
uint16_t u;
memcpy(&u, p, 2);
return bswap_16(u);
}
static inline uint32_t sg_get_unaligned_be32(const void *p)
{
uint32_t u;
memcpy(&u, p, 4);
return bswap_32(u);
}
static inline uint64_t sg_get_unaligned_be64(const void *p)
{
uint64_t u;
memcpy(&u, p, 8);
return bswap_64(u);
}
static inline void sg_put_unaligned_be16(uint16_t val, void *p)
{
uint16_t u = bswap_16(val);
memcpy(p, &u, 2);
}
static inline void sg_put_unaligned_be32(uint32_t val, void *p)
{
uint32_t u = bswap_32(val);
memcpy(p, &u, 4);
}
static inline void sg_put_unaligned_be64(uint64_t val, void *p)
{
uint64_t u = bswap_64(val);
memcpy(p, &u, 8);
}
static inline uint16_t sg_get_unaligned_le16(const void *p)
{
uint16_t u;
memcpy(&u, p, 2);
return u;
}
static inline uint32_t sg_get_unaligned_le32(const void *p)
{
uint32_t u;
memcpy(&u, p, 4);
return u;
}