From cedcc55796b73ce6fae2a9acf3120972738db8c7 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 27 Mar 2011 18:00:55 +1100 Subject: [PATCH] Add SG3 utils patch to the patches subdirectory --- patches/README | 25 + patches/sg3_utils-1.30.patch | 1164 ++++++++++++++++++++++++++++++++++ 2 files changed, 1189 insertions(+) create mode 100644 patches/README create mode 100644 patches/sg3_utils-1.30.patch diff --git a/patches/README b/patches/README new file mode 100644 index 0000000..66adefd --- /dev/null +++ b/patches/README @@ -0,0 +1,25 @@ +This directory contains patches to other packages to make them iSCSI +aware. + +sg3_utils-1.30.patch +==================== +This patch adds iscsi support to the SG3 package. +This is only added for the Linux platform, but adding to other platforms +supported by SG3 should be trivial. + +$ ./src/sg_inq iscsi://127.0.0.1/iqn.ronnie.test/1 +standard INQUIRY: + PQual=0 Device_type=0 RMB=0 version=0x05 [SPC-3] + [AERC=0] [TrmTsk=1] NormACA=0 HiSUP=0 Resp_data_format=2 + SCCS=0 ACC=0 TPGS=0 3PC=0 Protect=0 BQue=0 + EncServ=0 MultiP=0 [MChngr=0] [ACKREQQ=0] Addr16=0 + [RelAdr=0] WBus16=0 Sync=0 Linked=0 [TranDis=0] CmdQue=1 + [SPI: Clocking=0x0 QAS=0 IUS=0] + length=66 (0x42) Peripheral device type: disk + Vendor identification: IET + Product identification: VIRTUAL-DISK + Product revision level: 0001 + Unit serial number: beaf11 + + + diff --git a/patches/sg3_utils-1.30.patch b/patches/sg3_utils-1.30.patch new file mode 100644 index 0000000..16928bb --- /dev/null +++ b/patches/sg3_utils-1.30.patch @@ -0,0 +1,1164 @@ +commit e0f2b89c4886b5650054418321960980848fce51 +Author: Ronnie Sahlberg +Date: Sun Dec 5 09:08:20 2010 +1100 + + iscsi support + +diff --git a/configure.ac b/configure.ac +index 5c7314f..f7c9867 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -76,4 +76,34 @@ AC_ARG_ENABLE([win32-spt-direct], + AC_DEFINE_UNQUOTED(WIN32_SPT_DIRECT, 1, [enable Win32 SPT Direct], ) + ) + ++ ++AC_MSG_CHECKING(if libiscsi is available) ++ac_save_CFLAGS="$CFLAGS" ++ac_save_LIBS="$LIBS" ++CFLAGS="" ++LIBS="-liscsi" ++AC_TRY_RUN([ ++/* ++ * Just see if we can compile/link with libiscsi ++ */ ++#include ++int main(int argc, const char *argv[]) ++{ ++ iscsi_create_context(""); ++ return 0; ++} ++], ac_cv_have_libiscsi=yes, ac_cv_have_libiscsi=no, ++ [echo $ac_n "compile with LIBISCSI. Assuming OK... $ac_c" ++ ac_cv_have_libiscsi=yes]) ++CFLAGS="$ac_save_CFLAGS" ++LIBS="$ac_save_LIBS" ++if test "$ac_cv_have_libiscsi" = yes ; then ++ AC_MSG_RESULT(yes) ++ AC_SUBST([libiscsi], ['-liscsi']) ++ AC_DEFINE_UNQUOTED(CONFIG_LIBISCSI, 1, [we have libiscsi support], ) ++else ++ AC_MSG_RESULT(no) ++ AC_SUBST([libiscsi], ['']) ++fi ++ + AC_OUTPUT(Makefile include/Makefile lib/Makefile src/Makefile doc/Makefile) +diff --git a/include/sg_pt_iscsi.h b/include/sg_pt_iscsi.h +new file mode 100644 +index 0000000..f849eb0 +--- /dev/null ++++ b/include/sg_pt_iscsi.h +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2010 Ronnie Sahlberg ++ * All rights reserved. ++ * Use of this source code is governed by a BSD-style ++ * license that can be found in the BSD_LICENSE file. ++ */ ++ ++extern struct sg_context *iscsi; ++ ++#define ISCSI_FAKE_FD 0x7fffffff ++ ++int do_iscsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose); ++struct sg_pt_base *construct_iscsi_pt_obj(void); ++void clear_iscsi_pt_obj(struct sg_pt_base * vp); ++void destruct_iscsi_pt_obj(struct sg_pt_base * vp); ++void set_iscsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len); ++void set_iscsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len); ++void set_iscsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len); ++void set_iscsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len); ++int get_iscsi_pt_resid(const struct sg_pt_base * vp); ++int get_iscsi_pt_result_category(const struct sg_pt_base * vp); ++int get_iscsi_pt_os_err(const struct sg_pt_base * vp); ++int get_iscsi_pt_sense_len(const struct sg_pt_base * vp); ++void set_iscsi_pt_packet_id(struct sg_pt_base * vp, int pack_id); ++int iscsi_pt_close_device(int device_fd); ++char *get_iscsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b); ++int get_iscsi_pt_transport_err(const struct sg_pt_base * vp); ++char *get_iscsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b); ++void set_iscsi_pt_tag(struct sg_pt_base * vp, uint64_t tag); ++void set_iscsi_pt_task_management(struct sg_pt_base * vp, int tmf_code); ++void set_iscsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority); ++int get_iscsi_pt_duration_ms(const struct sg_pt_base * vp); ++int get_iscsi_pt_status_response(const struct sg_pt_base * vp); ++int iscsi_pt_open_device(const char *device_name, int read_only, int verbose); +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 3d5213e..6990f12 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -8,6 +8,7 @@ libsgutils2_la_SOURCES = \ + sg_cmds_extra.c \ + sg_cmds_mmc.c \ + sg_pt_common.c \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c + +@@ -33,6 +34,7 @@ libsgutils2_la_SOURCES = \ + sg_pt_win32.c + + EXTRA_libsgutils2_la_SOURCES = \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c \ + sg_pt_freebsd.c \ +@@ -55,6 +57,7 @@ libsgutils2_la_SOURCES = \ + sg_pt_win32.c + + EXTRA_libsgutils2_la_SOURCES = \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c \ + sg_pt_freebsd.c \ +@@ -77,6 +80,7 @@ libsgutils2_la_SOURCES = \ + sg_pt_freebsd.c + + EXTRA_libsgutils2_la_SOURCES = \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c \ + sg_linux_inc.h \ +@@ -100,6 +104,7 @@ libsgutils2_la_SOURCES = \ + sg_pt_solaris.c + + EXTRA_libsgutils2_la_SOURCES = \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c \ + sg_linux_inc.h \ +@@ -123,6 +128,7 @@ libsgutils2_la_SOURCES = \ + sg_pt_osf1.c + + EXTRA_libsgutils2_la_SOURCES = \ ++ sg_pt_iscsi.c \ + sg_pt_linux.c \ + sg_io_linux.c \ + sg_pt_freebsd.c \ +@@ -140,7 +146,7 @@ lib_LTLIBRARIES = libsgutils2.la + + libsgutils2_la_LDFLAGS = -version-info 2:0:0 + +-libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@ ++libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@ @libiscsi@ + libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@ + + +diff --git a/lib/sg_pt_iscsi.c b/lib/sg_pt_iscsi.c +new file mode 100644 +index 0000000..8f09baf +--- /dev/null ++++ b/lib/sg_pt_iscsi.c +@@ -0,0 +1,392 @@ ++/* ++ * Copyright (c) 2010 Ronnie Sahlberg ++ * All rights reserved. ++ * Use of this source code is governed by a BSD-style ++ * license that can be found in the BSD_LICENSE file. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#ifdef CONFIG_LIBISCSI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "sg_lib.h" ++#include "sg_pt.h" ++#include "sg_linux_inc.h" ++#include "sg_pt_iscsi.h" ++ ++struct sg_context { ++ struct iscsi_context *context; ++ int lun; ++}; ++struct sg_context *iscsi; ++ ++struct sg_pt_iscsi { ++ int os_err; ++ ++ int xferdir; ++ const unsigned char *cdb; ++ int cdb_len; ++ unsigned char *sense; ++ int sense_len; ++ int max_sense_len; ++ struct iscsi_data datain; ++ struct iscsi_data dataout; ++ int device_status; ++}; ++ ++struct sg_pt_base { ++ struct sg_pt_iscsi impl; ++}; ++ ++int ++do_iscsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ struct scsi_task *task; ++ struct iscsi_data *data = NULL; ++ ++ /* keep compiler happy */ ++ time_secs = time_secs; ++ verbose = verbose; ++ fd = fd; ++ ++ task = malloc(sizeof(struct scsi_task)); ++ bzero(task, sizeof(struct scsi_task)); ++ ++ ptp->os_err = 0; ++ ++ task->cdb_size = ptp->cdb_len; ++ memcpy(&task->cdb[0], ptp->cdb, task->cdb_size); ++ ++ task->xfer_dir = ptp->xferdir; ++ switch (task->xfer_dir) { ++ case SCSI_XFER_NONE: ++ task->expxferlen = 0; ++ break; ++ case SCSI_XFER_READ: ++ task->expxferlen = ptp->datain.size; ++ break; ++ case SCSI_XFER_WRITE: ++ task->expxferlen = ptp->dataout.size; ++ data = &ptp->dataout; ++ break; ++ } ++ ++ if (iscsi_scsi_command_sync(iscsi->context, iscsi->lun, task, data) == NULL) { ++ printf("error\n"); ++ scsi_free_scsi_task(task); ++ ptp->os_err = -1; ++ return -1; ++ } ++ ++ ptp->device_status = task->status; ++ if (task->status == SCSI_STATUS_GOOD) { ++ memcpy(ptp->datain.data, task->datain.data, ++ task->datain.sizedatain.size? ++ task->datain.size:ptp->datain.size); ++ scsi_free_scsi_task(task); ++ return 0; ++ } ++ ++ if (task->status == SCSI_STATUS_CHECK_CONDITION) { ++ /* +2 is to strip off the initial "length" and just copy the sense blob itself */ ++ ptp->sense_len = (ptp->max_sense_len<(task->datain.size-2))?ptp->max_sense_len:(task->datain.size-2); ++ memcpy(ptp->sense, task->datain.data+2, ptp->sense_len); ++ scsi_free_scsi_task(task); ++ return 0; ++ } ++ return -1; ++} ++ ++ ++struct sg_pt_base * ++construct_iscsi_pt_obj(void) ++{ ++ struct sg_pt_iscsi * ptp; ++ ++ ptp = (struct sg_pt_iscsi *) ++ calloc(1, sizeof(struct sg_pt_iscsi)); ++ ptp->xferdir = SCSI_XFER_NONE; ++ return (struct sg_pt_base *)ptp; ++} ++ ++void ++clear_iscsi_pt_obj(struct sg_pt_base * vp) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ if (ptp) { ++ memset(ptp, 0, sizeof(struct sg_pt_iscsi)); ++ ptp->xferdir = SCSI_XFER_READ; ++ } ++} ++ ++void ++destruct_iscsi_pt_obj(struct sg_pt_base * vp) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ if (ptp) ++ free(ptp); ++} ++ ++void ++set_iscsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, ++ int cdb_len) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ ptp->cdb = cdb; ++ ptp->cdb_len = cdb_len; ++} ++ ++void ++set_iscsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, ++ int max_sense_len) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ memset(sense, 0, max_sense_len); ++ ptp->sense = sense; ++ ptp->max_sense_len = max_sense_len; ++} ++ ++void ++set_iscsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, ++ int dxfer_len) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ if (dxfer_len > 0) { ++ ptp->datain.data = dxferp; ++ ptp->datain.size = dxfer_len; ++ ptp->xferdir = SCSI_XFER_READ; ++ } ++} ++ ++void ++set_iscsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, ++ int dxfer_len) ++{ ++ struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ if (dxfer_len > 0) { ++ ptp->dataout.data = (unsigned char *)dxferp; ++ ptp->dataout.size = dxfer_len; ++ ptp->xferdir = SCSI_XFER_WRITE; ++ } ++} ++ ++int ++get_iscsi_pt_resid(const struct sg_pt_base * vp) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ ++ return 0; ++} ++ ++int ++get_iscsi_pt_result_category(const struct sg_pt_base * vp) ++{ ++ const struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ if (ptp->os_err) ++ return SCSI_PT_RESULT_OS_ERR; ++ ++ if (ptp->device_status) ++ return SCSI_PT_RESULT_SENSE; ++ else ++ return SCSI_PT_RESULT_GOOD; ++} ++ ++int ++get_iscsi_pt_os_err(const struct sg_pt_base * vp) ++{ ++ const struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ return ptp->os_err; ++} ++ ++int ++get_iscsi_pt_sense_len(const struct sg_pt_base * vp) ++{ ++ const struct sg_pt_iscsi * ptp = &vp->impl; ++ ++ return ptp->sense_len; ++} ++ ++void ++set_iscsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ pack_id = pack_id; ++} ++ ++int ++iscsi_pt_close_device(int device_fd) ++{ ++ /* keep compiler happy */ ++ device_fd = device_fd; ++ ++ iscsi_logout_sync(iscsi->context); ++ iscsi_destroy_context(iscsi->context); ++ free(iscsi); ++ iscsi = NULL; ++ return 0; ++} ++ ++char * ++get_iscsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) ++{ ++ const struct sg_pt_iscsi * ptp = &vp->impl; ++ const char * cp; ++ ++ cp = safe_strerror(ptp->os_err); ++ strncpy(b, cp, max_b_len); ++ if ((int)strlen(cp) >= max_b_len) ++ b[max_b_len - 1] = '\0'; ++ return b; ++} ++ ++int ++get_iscsi_pt_transport_err(const struct sg_pt_base * vp) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ ++ return 0; ++} ++ ++char * ++get_iscsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, ++ char * b) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ max_b_len = max_b_len; ++ b = b; ++ ++ return ""; ++} ++ ++void ++set_iscsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ tag = tag; ++} ++ ++void ++set_iscsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ tmf_code = tmf_code; ++} ++ ++void ++set_iscsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ attribute = attribute; ++ priority = priority; ++} ++ ++int ++get_iscsi_pt_duration_ms(const struct sg_pt_base * vp) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ ++ return 0; ++} ++ ++ ++int ++get_iscsi_pt_status_response(const struct sg_pt_base * vp) ++{ ++ /* keep compiler happy */ ++ vp = vp; ++ ++ return 0; ++} ++ ++int ++iscsi_pt_open_device(const char *device_name, int read_only, int verbose) ++{ ++ char *tmpstr = NULL, *portal, *target, *lun; ++ ++ /* keep compiler happy */ ++ read_only = read_only; ++ verbose = verbose; ++ ++ if (strncmp(device_name, "iscsi://", 8)) { ++ return -1; ++ } ++ ++ tmpstr = strdup(device_name); ++ portal = tmpstr+8; ++ target = index(portal, '/'); ++ if (!target) { ++ fprintf(stderr, "Invalid iscsi url : %s\n", device_name); ++ free(tmpstr); ++ return -1; ++ } ++ *target++ = 0; ++ lun = index(target, '/'); ++ if (!lun) { ++ fprintf(stderr, "Invalid iscsi url : %s\n", device_name); ++ free(tmpstr); ++ return -1; ++ } ++ *lun++ = 0; ++ ++ iscsi = malloc(sizeof(struct sg_context)); ++ iscsi->context = iscsi_create_context("iqn.2010-12.org.sg3utils"); ++ if (!iscsi->context) { ++ fprintf(stderr, "Failed to create iscsi context for url %s\n", device_name); ++ free(tmpstr); ++ free(iscsi); ++ iscsi = NULL; ++ return -1; ++ } ++ ++ iscsi->lun = atoi(lun); ++ iscsi_set_targetname(iscsi->context, target); ++ iscsi_set_session_type(iscsi->context, ISCSI_SESSION_NORMAL); ++ iscsi_set_header_digest(iscsi->context, ISCSI_HEADER_DIGEST_NONE_CRC32C); ++ ++ if (iscsi_full_connect_sync(iscsi->context, portal, iscsi->lun) != 0) { ++ fprintf(stderr, "iSCSI login failed: %s\n", iscsi_get_error(iscsi->context)); ++ free(tmpstr); ++ iscsi_destroy_context(iscsi->context); ++ free(iscsi); ++ iscsi = NULL; ++ return -1; ++ } ++ ++ return ISCSI_FAKE_FD; ++} ++ ++#endif +diff --git a/lib/sg_pt_linux.c b/lib/sg_pt_linux.c +index 3ce4cf6..4e5221b 100644 +--- a/lib/sg_pt_linux.c ++++ b/lib/sg_pt_linux.c +@@ -27,6 +27,10 @@ + #include "sg_lib.h" + #include "sg_linux_inc.h" + ++#ifdef CONFIG_LIBISCSI ++#include "sg_pt_iscsi.h" ++#endif ++ + #define DEF_TIMEOUT 60000 /* 60,000 millisecs (60 seconds) */ + + static const char * linux_host_bytes[] = { +@@ -117,6 +121,12 @@ scsi_pt_open_flags(const char * device_name, int flags, int verbose) + { + int fd; + ++#ifdef CONFIG_LIBISCSI ++ if (!strncmp(device_name, "iscsi://", 8)) { ++ return iscsi_pt_open_device(device_name, flags, verbose); ++ } ++#endif ++ + if (verbose > 1) { + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; +@@ -135,6 +145,12 @@ scsi_pt_close_device(int device_fd) + { + int res; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return iscsi_pt_close_device(device_fd); ++ } ++#endif ++ + res = close(device_fd); + if (res < 0) + res = -errno; +@@ -147,6 +163,12 @@ construct_scsi_pt_obj() + { + struct sg_pt_linux_scsi * ptp; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return construct_iscsi_pt_obj(); ++ } ++#endif ++ + ptp = (struct sg_pt_linux_scsi *) + calloc(1, sizeof(struct sg_pt_linux_scsi)); + if (ptp) { +@@ -161,6 +183,12 @@ destruct_scsi_pt_obj(struct sg_pt_base * vp) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return destruct_iscsi_pt_obj(vp); ++ } ++#endif ++ + if (ptp) + free(ptp); + } +@@ -170,6 +198,12 @@ clear_scsi_pt_obj(struct sg_pt_base * vp) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return clear_iscsi_pt_obj(vp); ++ } ++#endif ++ + if (ptp) { + memset(ptp, 0, sizeof(struct sg_pt_linux_scsi)); + ptp->io_hdr.interface_id = 'S'; +@@ -183,6 +217,12 @@ set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_cdb(vp, cdb, cdb_len); ++ } ++#endif ++ + if (ptp->io_hdr.cmdp) + ++ptp->in_err; + ptp->io_hdr.cmdp = (unsigned char *)cdb; +@@ -195,6 +235,12 @@ set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_sense(vp, sense, max_sense_len); ++ } ++#endif ++ + if (ptp->io_hdr.sbp) + ++ptp->in_err; + memset(sense, 0, max_sense_len); +@@ -209,6 +255,12 @@ set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_data_in(vp, dxferp, dxfer_len); ++ } ++#endif ++ + if (ptp->io_hdr.dxferp) + ++ptp->in_err; + if (dxfer_len > 0) { +@@ -225,6 +277,12 @@ set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_data_out(vp, dxferp, dxfer_len); ++ } ++#endif ++ + if (ptp->io_hdr.dxferp) + ++ptp->in_err; + if (dxfer_len > 0) { +@@ -239,6 +297,13 @@ set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_packet_id(vp, pack_id); ++ return; ++ } ++#endif ++ + ptp->io_hdr.pack_id = pack_id; + } + +@@ -247,6 +312,13 @@ set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_tag(vp, tag); ++ return; ++ } ++#endif ++ + ++ptp->in_err; + tag = tag; /* dummy to silence compiler */ + } +@@ -257,6 +329,13 @@ set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_task_management(vp, tmf_code); ++ return; ++ } ++#endif ++ + ++ptp->in_err; + tmf_code = tmf_code; /* dummy to silence compiler */ + } +@@ -266,6 +345,13 @@ set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_task_attr(vp, attribute, priority); ++ return; ++ } ++#endif ++ + ++ptp->in_err; + attribute = attribute; /* dummy to silence compiler */ + priority = priority; /* dummy to silence compiler */ +@@ -303,6 +389,12 @@ do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return do_iscsi_pt(vp, fd, time_secs, verbose); ++ } ++#endif ++ + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; + ptp->os_err = 0; +@@ -339,6 +431,12 @@ get_scsi_pt_result_category(const struct sg_pt_base * vp) + int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK; + int scsi_st = ptp->io_hdr.status & 0x7e; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_result_category(vp); ++ } ++#endif ++ + if (ptp->os_err) + return SCSI_PT_RESULT_OS_ERR; + else if (ptp->io_hdr.host_status) +@@ -360,6 +458,12 @@ get_scsi_pt_resid(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_resid(vp); ++ } ++#endif ++ + return ptp->io_hdr.resid; + } + +@@ -368,6 +472,12 @@ get_scsi_pt_status_response(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_status_response(vp); ++ } ++#endif ++ + return ptp->io_hdr.status; + } + +@@ -376,6 +486,12 @@ get_scsi_pt_sense_len(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_sense_len(vp); ++ } ++#endif ++ + return ptp->io_hdr.sb_len_wr; + } + +@@ -384,6 +500,12 @@ get_scsi_pt_duration_ms(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_duration_ms(vp); ++ } ++#endif ++ + return ptp->io_hdr.duration; + } + +@@ -392,6 +514,12 @@ get_scsi_pt_transport_err(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_transport_err(vp); ++ } ++#endif ++ + return (ptp->io_hdr.host_status << 8) + ptp->io_hdr.driver_status; + } + +@@ -400,6 +528,12 @@ get_scsi_pt_os_err(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_os_err(vp); ++ } ++#endif ++ + return ptp->os_err; + } + +@@ -416,6 +550,12 @@ get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, + const char * driv_cp = "invalid"; + const char * sugg_cp = "invalid"; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_transport_err_str(vp, max_b_len, b); ++ } ++#endif ++ + m = max_b_len; + n = 0; + if (hs) { +@@ -451,6 +591,12 @@ get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) + const struct sg_pt_linux_scsi * ptp = &vp->impl; + const char * cp; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_os_err_str(vp, max_b_len, b); ++ } ++#endif ++ + cp = safe_strerror(ptp->os_err); + strncpy(b, cp, max_b_len); + if ((int)strlen(cp) >= max_b_len) +@@ -567,6 +713,12 @@ scsi_pt_open_flags(const char * device_name, int flags, int verbose) + { + int fd; + ++#ifdef CONFIG_LIBISCSI ++ if (!strncmp(device_name, "iscsi://", 8)) { ++ return iscsi_pt_open_device(device_name, flags, verbose); ++ } ++#endif ++ + if (! bsg_major_checked) { + bsg_major_checked = 1; + find_bsg_major(verbose); +@@ -589,6 +741,12 @@ scsi_pt_close_device(int device_fd) + { + int res; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return iscsi_pt_close_device(device_fd); ++ } ++#endif ++ + res = close(device_fd); + if (res < 0) + res = -errno; +@@ -601,6 +759,12 @@ construct_scsi_pt_obj() + { + struct sg_pt_linux_scsi * ptp; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return construct_iscsi_pt_obj(); ++ } ++#endif ++ + ptp = (struct sg_pt_linux_scsi *) + calloc(1, sizeof(struct sg_pt_linux_scsi)); + if (ptp) { +@@ -620,6 +784,12 @@ destruct_scsi_pt_obj(struct sg_pt_base * vp) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return destruct_iscsi_pt_obj(vp); ++ } ++#endif ++ + if (ptp) + free(ptp); + } +@@ -629,6 +799,12 @@ clear_scsi_pt_obj(struct sg_pt_base * vp) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return clear_iscsi_pt_obj(vp); ++ } ++#endif ++ + if (ptp) { + memset(ptp, 0, sizeof(struct sg_pt_linux_scsi)); + ptp->io_hdr.guard = 'Q'; +@@ -647,6 +823,12 @@ set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_cdb(vp, cdb, cdb_len); ++ } ++#endif ++ + if (ptp->io_hdr.request) + ++ptp->in_err; + /* C99 has intptr_t instead of long */ +@@ -660,6 +842,12 @@ set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_sense(vp, sense, max_sense_len); ++ } ++#endif ++ + if (ptp->io_hdr.response) + ++ptp->in_err; + memset(sense, 0, max_sense_len); +@@ -674,6 +862,12 @@ set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_data_in(vp, dxferp, dxfer_len); ++ } ++#endif ++ + if (ptp->io_hdr.din_xferp) + ++ptp->in_err; + if (dxfer_len > 0) { +@@ -689,6 +883,12 @@ set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return set_iscsi_pt_data_out(vp, dxferp, dxfer_len); ++ } ++#endif ++ + if (ptp->io_hdr.dout_xferp) + ++ptp->in_err; + if (dxfer_len > 0) { +@@ -702,6 +902,13 @@ set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_packet_id(vp, pack_id); ++ return; ++ } ++#endif ++ + ptp->io_hdr.spare_in = pack_id; + } + +@@ -710,6 +917,13 @@ set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_tag(vp, tag); ++ return; ++ } ++#endif ++ + ptp->io_hdr.request_tag = tag; + } + +@@ -719,6 +933,13 @@ set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_task_management(vp, tmf_code); ++ return; ++ } ++#endif ++ + ptp->io_hdr.subprotocol = 1; /* SCSI task management function */ + ptp->tmf_request[0] = (unsigned char)tmf_code; /* assume it fits */ + ptp->io_hdr.request = (__u64)(long)(&(ptp->tmf_request[0])); +@@ -730,6 +951,12 @@ set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) + { + struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ set_iscsi_pt_task_attr(vp, attribute, priority); ++ return; ++ } ++#endif + ptp->io_hdr.request_attr = attribute; + ptp->io_hdr.request_priority = priority; + } +@@ -756,6 +983,12 @@ get_scsi_pt_resid(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_resid(vp); ++ } ++#endif ++ + return ptp->io_hdr.din_resid; + } + +@@ -764,6 +997,12 @@ get_scsi_pt_status_response(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_status_response(vp); ++ } ++#endif ++ + return ptp->io_hdr.device_status; + } + +@@ -772,6 +1011,12 @@ get_scsi_pt_sense_len(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_sense_len(vp); ++ } ++#endif ++ + return ptp->io_hdr.response_len; + } + +@@ -780,6 +1025,12 @@ get_scsi_pt_duration_ms(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_duration_ms(vp); ++ } ++#endif ++ + return ptp->io_hdr.duration; + } + +@@ -788,6 +1039,12 @@ get_scsi_pt_transport_err(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_transport_err(vp); ++ } ++#endif ++ + return ptp->io_hdr.transport_status; + } + +@@ -805,6 +1062,12 @@ get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, + const char * driv_cp = "invalid"; + const char * sugg_cp = "invalid"; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_transport_err_str(vp, max_b_len, b); ++ } ++#endif ++ + m = max_b_len; + n = 0; + if (hs) { +@@ -841,6 +1104,12 @@ get_scsi_pt_result_category(const struct sg_pt_base * vp) + int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK; + int scsi_st = ptp->io_hdr.device_status & 0x7e; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_result_category(vp); ++ } ++#endif ++ + if (ptp->os_err) + return SCSI_PT_RESULT_OS_ERR; + else if (ptp->io_hdr.transport_status) +@@ -862,6 +1131,12 @@ get_scsi_pt_os_err(const struct sg_pt_base * vp) + { + const struct sg_pt_linux_scsi * ptp = &vp->impl; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_os_err(vp); ++ } ++#endif ++ + return ptp->os_err; + } + +@@ -871,6 +1146,12 @@ get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) + const struct sg_pt_linux_scsi * ptp = &vp->impl; + const char * cp; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return get_iscsi_pt_os_err_str(vp, max_b_len, b); ++ } ++#endif ++ + cp = safe_strerror(ptp->os_err); + strncpy(b, cp, max_b_len); + if ((int)strlen(cp) >= max_b_len) +@@ -945,6 +1226,12 @@ do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) + struct sg_pt_linux_scsi * ptp = &vp->impl; + void * p; + ++#ifdef CONFIG_LIBISCSI ++ if (iscsi) { ++ return do_iscsi_pt(vp, fd, time_secs, verbose); ++ } ++#endif ++ + if (! bsg_major_checked) { + bsg_major_checked = 1; + find_bsg_major(verbose);