diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2021-06-23 18:09:48 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2021-06-23 18:09:48 +0000 |
commit | 303f8c98ee28150285d69bd213970144fe224da3 (patch) | |
tree | 3cdbf0cc482229b65481fe30049c92fa3c2f1faa /lib | |
parent | bee57c535c29a01cadfaa660d8c0182288960c33 (diff) | |
download | sg3_utils-303f8c98ee28150285d69bd213970144fe224da3.tar.gz |
Haiku OS support, add pt function list in sg_pt_dummy.c; add slices to sg_mrq_dd
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@905 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 12 | ||||
-rw-r--r-- | lib/Makefile.in | 34 | ||||
-rw-r--r-- | lib/sg_pt_common.c | 4 | ||||
-rw-r--r-- | lib/sg_pt_dummy.c | 83 | ||||
-rw-r--r-- | lib/sg_pt_haiku.c | 572 | ||||
-rw-r--r-- | lib/sg_pt_osf1.c | 48 | ||||
-rw-r--r-- | lib/sg_pt_solaris.c | 32 |
7 files changed, 769 insertions, 16 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index f04c7778..97410dc3 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -42,6 +42,14 @@ if OS_OSF libsgutils2_la_SOURCES += sg_pt_osf1.c endif +if OS_HAIKU +if PT_DUMMY +libsgutils2_la_SOURCES += sg_pt_dummy.c +else +libsgutils2_la_SOURCES += sg_pt_haiku.c +endif +endif + if OS_NETBSD libsgutils2_la_SOURCES += sg_pt_dummy.c endif @@ -50,6 +58,10 @@ if OS_OPENBSD libsgutils2_la_SOURCES += sg_pt_dummy.c endif +if OS_OTHER +libsgutils2_la_SOURCES += sg_pt_dummy.c +endif + if DEBUG # This is active if --enable-debug given to ./configure # removed -Wduplicated-branches because needs gcc-8 diff --git a/lib/Makefile.in b/lib/Makefile.in index 4e12ff91..0fdc8a37 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -100,8 +100,11 @@ host_triplet = @host@ @OS_FREEBSD_TRUE@@PT_DUMMY_FALSE@am__append_6 = sg_pt_freebsd.c @OS_SOLARIS_TRUE@am__append_7 = sg_pt_solaris.c @OS_OSF_TRUE@am__append_8 = sg_pt_osf1.c -@OS_NETBSD_TRUE@am__append_9 = sg_pt_dummy.c -@OS_OPENBSD_TRUE@am__append_10 = sg_pt_dummy.c +@OS_HAIKU_TRUE@@PT_DUMMY_TRUE@am__append_9 = sg_pt_dummy.c +@OS_HAIKU_TRUE@@PT_DUMMY_FALSE@am__append_10 = sg_pt_haiku.c +@OS_NETBSD_TRUE@am__append_11 = sg_pt_dummy.c +@OS_OPENBSD_TRUE@am__append_12 = sg_pt_dummy.c +@OS_OTHER_TRUE@am__append_13 = sg_pt_dummy.c subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -145,7 +148,7 @@ am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ sg_cmds_basic.c sg_cmds_basic2.c sg_cmds_extra.c sg_cmds_mmc.c \ sg_pt_common.c sg_pt_dummy.c sg_pt_linux.c sg_io_linux.c \ sg_pt_linux_nvme.c sg_pt_win32.c sg_pt_freebsd.c \ - sg_pt_solaris.c sg_pt_osf1.c + sg_pt_solaris.c sg_pt_osf1.c sg_pt_haiku.c @OS_LINUX_TRUE@@PT_DUMMY_TRUE@am__objects_1 = sg_pt_dummy.lo @OS_LINUX_TRUE@@PT_DUMMY_FALSE@am__objects_2 = sg_pt_linux.lo \ @OS_LINUX_TRUE@@PT_DUMMY_FALSE@ sg_io_linux.lo \ @@ -156,14 +159,18 @@ am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ @OS_FREEBSD_TRUE@@PT_DUMMY_FALSE@am__objects_6 = sg_pt_freebsd.lo @OS_SOLARIS_TRUE@am__objects_7 = sg_pt_solaris.lo @OS_OSF_TRUE@am__objects_8 = sg_pt_osf1.lo -@OS_NETBSD_TRUE@am__objects_9 = sg_pt_dummy.lo -@OS_OPENBSD_TRUE@am__objects_10 = sg_pt_dummy.lo +@OS_HAIKU_TRUE@@PT_DUMMY_TRUE@am__objects_9 = sg_pt_dummy.lo +@OS_HAIKU_TRUE@@PT_DUMMY_FALSE@am__objects_10 = sg_pt_haiku.lo +@OS_NETBSD_TRUE@am__objects_11 = sg_pt_dummy.lo +@OS_OPENBSD_TRUE@am__objects_12 = sg_pt_dummy.lo +@OS_OTHER_TRUE@am__objects_13 = sg_pt_dummy.lo am_libsgutils2_la_OBJECTS = sg_lib.lo sg_lib_data.lo sg_cmds_basic.lo \ sg_cmds_basic2.lo sg_cmds_extra.lo sg_cmds_mmc.lo \ sg_pt_common.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \ - $(am__objects_9) $(am__objects_10) + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) libsgutils2_la_OBJECTS = $(am_libsgutils2_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -193,9 +200,10 @@ am__depfiles_remade = ./$(DEPDIR)/sg_cmds_basic.Plo \ ./$(DEPDIR)/sg_cmds_mmc.Plo ./$(DEPDIR)/sg_io_linux.Plo \ ./$(DEPDIR)/sg_lib.Plo ./$(DEPDIR)/sg_lib_data.Plo \ ./$(DEPDIR)/sg_pt_common.Plo ./$(DEPDIR)/sg_pt_dummy.Plo \ - ./$(DEPDIR)/sg_pt_freebsd.Plo ./$(DEPDIR)/sg_pt_linux.Plo \ - ./$(DEPDIR)/sg_pt_linux_nvme.Plo ./$(DEPDIR)/sg_pt_osf1.Plo \ - ./$(DEPDIR)/sg_pt_solaris.Plo ./$(DEPDIR)/sg_pt_win32.Plo + ./$(DEPDIR)/sg_pt_freebsd.Plo ./$(DEPDIR)/sg_pt_haiku.Plo \ + ./$(DEPDIR)/sg_pt_linux.Plo ./$(DEPDIR)/sg_pt_linux_nvme.Plo \ + ./$(DEPDIR)/sg_pt_osf1.Plo ./$(DEPDIR)/sg_pt_solaris.Plo \ + ./$(DEPDIR)/sg_pt_win32.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -350,6 +358,8 @@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ +os_cflags = @os_cflags@ +os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -368,7 +378,8 @@ libsgutils2_la_SOURCES = sg_lib.c sg_lib_data.c sg_cmds_basic.c \ $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) $(am__append_6) \ $(am__append_7) $(am__append_8) $(am__append_9) \ - $(am__append_10) + $(am__append_10) $(am__append_11) $(am__append_12) \ + $(am__append_13) @DEBUG_FALSE@DBG_CFLAGS = # This is active if --enable-debug given to ./configure @@ -481,6 +492,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_haiku.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_linux.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_linux_nvme.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_osf1.Plo@am__quote@ # am--include-marker @@ -658,6 +670,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/sg_pt_common.Plo -rm -f ./$(DEPDIR)/sg_pt_dummy.Plo -rm -f ./$(DEPDIR)/sg_pt_freebsd.Plo + -rm -f ./$(DEPDIR)/sg_pt_haiku.Plo -rm -f ./$(DEPDIR)/sg_pt_linux.Plo -rm -f ./$(DEPDIR)/sg_pt_linux_nvme.Plo -rm -f ./$(DEPDIR)/sg_pt_osf1.Plo @@ -718,6 +731,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sg_pt_common.Plo -rm -f ./$(DEPDIR)/sg_pt_dummy.Plo -rm -f ./$(DEPDIR)/sg_pt_freebsd.Plo + -rm -f ./$(DEPDIR)/sg_pt_haiku.Plo -rm -f ./$(DEPDIR)/sg_pt_linux.Plo -rm -f ./$(DEPDIR)/sg_pt_linux_nvme.Plo -rm -f ./$(DEPDIR)/sg_pt_osf1.Plo diff --git a/lib/sg_pt_common.c b/lib/sg_pt_common.c index 60ecaa6c..345aec39 100644 --- a/lib/sg_pt_common.c +++ b/lib/sg_pt_common.c @@ -31,8 +31,10 @@ #include "sg_pt_nvme.h" #endif -static const char * scsi_pt_version_str = "3.17 20210503"; +static const char * scsi_pt_version_str = "3.18 20210617"; +/* List of external functions that need to be defined for each OS are + * listed at the top of sg_pt_dummy.c */ const char * scsi_pt_version() diff --git a/lib/sg_pt_dummy.c b/lib/sg_pt_dummy.c index be84b503..d746c1ad 100644 --- a/lib/sg_pt_dummy.c +++ b/lib/sg_pt_dummy.c @@ -23,7 +23,53 @@ #include "sg_lib.h" #include "sg_pr2serr.h" -/* Version 1.01 20210609 */ +/* Version 1.02 20210618 */ + +/* List of function names with external linkage that need to be defined + * + * check_pt_file_handle + * clear_scsi_pt_obj + * construct_scsi_pt_obj + * construct_scsi_pt_obj_with_fd + * destruct_scsi_pt_obj + * do_scsi_pt + * do_nvm_pt + * get_pt_actual_lengths + * get_pt_duration_ns + * get_pt_file_handle + * get_pt_nvme_nsid + * get_pt_req_lengths + * get_pt_result + * get_scsi_pt_cdb_buf + * get_scsi_pt_cdb_len + * get_scsi_pt_duration_ms + * get_scsi_pt_os_err + * get_scsi_pt_os_err_str + * get_scsi_pt_resid + * get_scsi_pt_result_category + * get_scsi_pt_sense_buf + * get_scsi_pt_sense_len + * get_scsi_pt_status_response + * get_scsi_pt_transport_err + * get_scsi_pt_transport_err_str + * partial_clear_scsi_pt_obj + * pt_device_is_nvme + * scsi_pt_close_device + * scsi_pt_open_device + * scsi_pt_open_flags + * set_pt_file_handle + * set_pt_metadata_xfer + * set_scsi_pt_cdb + * set_scsi_pt_data_in + * set_scsi_pt_data_out + * set_scsi_pt_flags + * set_scsi_pt_packet_id + * set_scsi_pt_sense + * set_scsi_pt_tag + * set_scsi_pt_task_attr + * set_scsi_pt_task_management + * set_scsi_pt_transport_err + */ /* Simply defines all the functions needed by the pt interface (see sg_pt.h). * They do nothing. This allows decoding of hex files (e.g. with the --in= @@ -344,6 +390,15 @@ check_pt_file_handle(int device_fd, const char * device_name, int vb) return 0; } +/* Valid file handles (which is the return value) are >= 0 . Returns -1 + * if there is no valid file handle. */ +int +get_pt_file_handle(const struct sg_pt_base * vp) +{ + if (vp) { } + return -1; +} + /* If a NVMe block device (which includes the NSID) handle is associated * with 'vp', then its NSID is returned (values range from 0x1 to * 0xffffffe). Otherwise 0 is returned. */ @@ -360,3 +415,29 @@ get_pt_result(const struct sg_pt_base * vp) if (vp) { } return 0; } + +int +set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb) +{ + if (vp) { } + if (dev_han) { } + if (vb) { } + return 0; +} + +void +set_pt_metadata_xfer(struct sg_pt_base * vp, uint8_t * mdxferp, + uint32_t mdxfer_len, bool out_true) +{ + if (vp) { } + if (mdxferp) { } + if (mdxfer_len) { } + if (out_true) { } +} + +void +set_scsi_pt_transport_err(struct sg_pt_base * vp, int err) +{ + if (vp) { } + if (err) { } +} diff --git a/lib/sg_pt_haiku.c b/lib/sg_pt_haiku.c new file mode 100644 index 00000000..c9ed291c --- /dev/null +++ b/lib/sg_pt_haiku.c @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2017 Leorize. + * 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 <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <device/CAM.h> +#include <scsi.h> + +#include "sg_lib.h" +#include "sg_pt.h" + +#if defined(__GNUC__) || defined(__clang__) +static int pr2ws(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))); +#else +static int pr2ws(const char * fmt, ...); +#endif + +static int +pr2ws(const char * fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vfprintf(sg_warnings_strm ? sg_warnings_strm : stderr, fmt, args); + va_end(args); + return n; +} + +struct sg_pt_haiku_scsi { + raw_device_command raw_command; + size_t data_len; + int in_err; + int os_err; + int dev_fd; +}; + +struct sg_pt_base { + struct sg_pt_haiku_scsi impl; +}; + +/* Returns >= 0 if successful. If error in Unix returns negated errno. */ +int +scsi_pt_open_device(const char * device_name, bool read_only, int verbose) +{ + int oflags = O_NONBLOCK; + + oflags |= (read_only ? O_RDONLY : O_RDWR); + return scsi_pt_open_flags(device_name, oflags, verbose); +} + +/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed */ +/* together. The 'flags' argument is advisory and may be ignored. */ +/* Returns >= 0 if successful, otherwise returns negated errno. */ +int +scsi_pt_open_flags(const char * device_name, int flags, int verbose) +{ + int fd; + + if (verbose > 1) { + pr2ws("open %s with flags=0x%x\n", device_name, flags); + } + fd = open(device_name, flags); + if (fd < 0) + fd = -errno; + return fd; +} + +/* Returns 0 if successful. If error in Unix returns negated errno. */ +int +scsi_pt_close_device(int device_fd) +{ + int res; + + res = close(device_fd); + if (res < 0) + res = -errno; + return res; +} + +struct sg_pt_base * +construct_scsi_pt_obj_with_fd(int device_fd, int verbose) +{ + struct sg_pt_haiku_scsi * ptp; + + /* The following 2 lines are temporary. It is to avoid a NULL pointer + * crash when an old utility is used with a newer library built after + * the sg_warnings_strm cleanup */ + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; + + ptp = (struct sg_pt_haiku_scsi *) + calloc(1, sizeof(struct sg_pt_haiku_scsi)); + if (ptp) { + ptp->raw_command.flags = B_RAW_DEVICE_REPORT_RESIDUAL; + ptp->dev_fd = device_fd; + } else if (verbose) + pr2ws("%s: malloc() out of memory\n", __func__); + return (struct sg_pt_base *)ptp; +} + +struct sg_pt_base * +construct_scsi_pt_obj() +{ + return construct_scsi_pt_obj_with_fd(-1, 0); +} + +void +destruct_scsi_pt_obj(struct sg_pt_base * vp) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp) + free(ptp); +} + +void +clear_scsi_pt_obj(struct sg_pt_base * vp) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp) { + + int fd = ptp->dev_fd; + memset(ptp, 0, sizeof(struct sg_pt_haiku_scsi)); + ptp->dev_fd = fd; + ptp->raw_command.flags = B_RAW_DEVICE_REPORT_RESIDUAL; + } +} + +void +set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, + int cdb_len) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + for (int i = 0; i < 16; ++i) + if (ptp->raw_command.command[i]) + ++ptp->in_err; + memcpy(ptp->raw_command.command, cdb, cdb_len); + ptp->raw_command.command_length = (uint8)cdb_len; +} + +void +set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, + int max_sense_len) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->raw_command.sense_data) + ++ptp->in_err; + memset(sense, 0, max_sense_len); + ptp->raw_command.sense_data = sense; + ptp->raw_command.sense_data_length = max_sense_len; +} + +/* Setup for data transfer from device */ +void +set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, + int dxfer_len) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->raw_command.data) + ++ptp->in_err; + if (dxfer_len > 0) { + ptp->raw_command.data = dxferp; + ptp->raw_command.data_length = dxfer_len; + ptp->data_len = dxfer_len; + ptp->raw_command.flags |= B_RAW_DEVICE_DATA_IN; + } +} + +/* Setup for data transfer toward device */ +void +set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, + int dxfer_len) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->raw_command.data) + ++ptp->in_err; + if (dxfer_len > 0) { + ptp->raw_command.data = (unsigned char *)dxferp; + ptp->raw_command.data_length = dxfer_len; + ptp->data_len = dxfer_len; + ptp->raw_command.flags &= ~B_RAW_DEVICE_DATA_IN; + } +} + +void +set_scsi_pt_packet_id(struct sg_pt_base * vp __attribute__ ((unused)), + int pack_id __attribute__ ((unused))) +{ +} + +void +set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag __attribute__ ((unused))) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + ++ptp->in_err; +} + +void +set_scsi_pt_task_management(struct sg_pt_base * vp, + int tmf_code __attribute__ ((unused))) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + ++ptp->in_err; +} + +void +set_scsi_pt_task_attr(struct sg_pt_base * vp, + int attrib __attribute__ ((unused)), + int priority __attribute__ ((unused))) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + ++ptp->in_err; +} + +void +set_scsi_pt_flags(struct sg_pt_base * vp __attribute__ ((unused)), + int flags __attribute__ ((unused))) +{ +} + +/* 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 fd, int timeout_secs, int verbose) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + ptp->os_err = 0; + if (ptp->in_err) { + if (verbose) + pr2ws("Replicated or unused set_scsi_pt...\n"); + return SCSI_PT_DO_BAD_PARAMS; + } + if (fd >= 0) { + if ((ptp->dev_fd >= 0) && (fd != ptp->dev_fd)) { + if (verbose) + pr2ws("%s: file descriptor given to create() and here " + "differ\n", __func__); + return SCSI_PT_DO_BAD_PARAMS; + } + ptp->dev_fd = fd; + } else if (ptp->dev_fd < 0) { + if (verbose) + pr2ws("%s: invalid file descriptors\n", __func__); + return SCSI_PT_DO_BAD_PARAMS; + } else + fd = ptp->dev_fd; + + if (NULL == ptp->raw_command.command) { + if (verbose) + pr2ws("No SCSI command (cdb) given\n"); + return SCSI_PT_DO_BAD_PARAMS; + } + /* raw_command.timeout is in microseconds */ + ptp->raw_command.timeout = ((timeout_secs > 0) ? (timeout_secs * 1000000) : + CAM_TIME_DEFAULT); + + if (ioctl(fd, B_RAW_DEVICE_COMMAND, &ptp->raw_command) < 0) { + ptp->os_err = errno; + if (verbose > 1) + pr2ws("ioctl(B_RAW_DEVICE_COMMAND) failed: %s (errno=%d)\n", + safe_strerror(ptp->os_err), ptp->os_err); + return -ptp->os_err; + } + + return SCSI_PT_DO_START_OK; +} + +int +get_scsi_pt_result_category(const struct sg_pt_base * vp) +{ + int cam_status_masked; + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->os_err) + return SCSI_PT_RESULT_OS_ERR; + cam_status_masked = ptp->raw_command.cam_status & CAM_STATUS_MASK; + if (cam_status_masked != CAM_REQ_CMP && + cam_status_masked != CAM_REQ_CMP_ERR) + return SCSI_PT_RESULT_TRANSPORT_ERR; + else if ((SAM_STAT_CHECK_CONDITION == ptp->raw_command.scsi_status) || + (SAM_STAT_COMMAND_TERMINATED == ptp->raw_command.scsi_status)) + return SCSI_PT_RESULT_SENSE; + else if (ptp->raw_command.scsi_status) + return SCSI_PT_RESULT_STATUS; + else + return SCSI_PT_RESULT_GOOD; +} + +int +get_scsi_pt_resid(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + /* For various reasons Haiku return data_len - data_resid */ + return ptp->data_len - ptp->raw_command.data_length; +} + +int +get_scsi_pt_status_response(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return ptp->raw_command.scsi_status; +} + +uint8_t * +get_scsi_pt_sense_buf(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return (uint8_t *)ptp->raw_command.sense_data; +} + +int +get_scsi_pt_sense_len(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return ptp->raw_command.sense_data_length; +} + +int +get_scsi_pt_os_err(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return ptp->os_err; +} + +char * +get_scsi_pt_os_err_str(const struct sg_pt_base * vp __attribute__ ((unused)), + int max_b_len, char * b) +{ + const struct sg_pt_haiku_scsi * 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_scsi_pt_transport_err(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if ((ptp->raw_command.cam_status & CAM_STATUS_MASK) != CAM_REQ_CMP || + (ptp->raw_command.cam_status & CAM_STATUS_MASK) != CAM_REQ_CMP_ERR) + return ptp->raw_command.cam_status & CAM_STATUS_MASK; + + return 0; +} + +char * +get_scsi_pt_transport_err_str( + const struct sg_pt_base * vp __attribute__ ((unused)), + int max_b_len, char * b) +{ + strncpy(b, "no transport error available", max_b_len); + b[max_b_len - 1] = '\0'; + return b; +} + +int +get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused))) +{ + return -1; +} + +void +partial_clear_scsi_pt_obj(struct sg_pt_base * vp) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (NULL == ptp) + return; + ptp->in_err = 0; + ptp->os_err = 0; + ptp->data_len = 0; + ptp->raw_command.cam_status = 0; + ptp->raw_command.data_length = 0; +} + +bool pt_device_is_nvme(const struct sg_pt_base * vp __attribute__ ((unused))) +{ + return 0; +} + +int +check_pt_file_handle(int device_fd, const char * device_name, int vb) +{ + if (device_fd) {} + if (device_name) {} + if (vb) {} + return 1; /* guess it is a SCSI generic pass-though device */ +} + +int +do_nvm_pt(struct sg_pt_base * vp, int submq, int timeout_secs, int verbose) +{ + if (vp) { } + if (submq) { } + if (timeout_secs) { } + if (verbose) { } + return SCSI_PT_DO_NOT_SUPPORTED; +} + +void +get_pt_actual_lengths(const struct sg_pt_base * vp, int * act_dinp, + int * act_doutp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->data_len == 0) { + if (act_dinp) + *act_dinp = 0; + if (act_doutp) + *act_doutp = 0; + } else if (act_dinp && (ptp->raw_command.flags & B_RAW_DEVICE_DATA_IN)) { + /* "For various reasons Haiku return data_len - data_resid" */ + *act_dinp = ptp->raw_command.data_length; + if (act_doutp) + *act_doutp = 0; + } else if (act_doutp && + !(ptp->raw_command.flags & B_RAW_DEVICE_DATA_IN)) { + *act_doutp = ptp->raw_command.data_length; + if (act_dinp) + *act_dinp = 0; + } else { + if (act_dinp) + *act_dinp = 0; + if (act_doutp) + *act_doutp = 0; + } +} + +/* If not available return 0 otherwise return number of nanoseconds that the + * lower layers (and hardware) took to execute the command just completed. */ +uint64_t +get_pt_duration_ns(const struct sg_pt_base * vp __attribute__ ((unused))) +{ + return 0; +} + +/* Valid file handles (which is the return value) are >= 0 . Returns -1 + * if there is no valid file handle. */ +int +get_pt_file_handle(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return ptp->dev_fd; +} + + +/* If a NVMe block device (which includes the NSID) handle is associated + * with 'vp', then its NSID is returned (values range from 0x1 to + * 0xffffffe). Otherwise 0 is returned. */ +uint32_t +get_pt_nvme_nsid(const struct sg_pt_base * vp) +{ + if (vp) { } + return 0; +} + +void +get_pt_req_lengths(const struct sg_pt_base * vp, int * req_dinp, + int * req_doutp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (ptp->data_len == 0) { + if (req_dinp) + *req_dinp = 0; + if (req_doutp) + *req_doutp = 0; + } else if (req_dinp && (ptp->raw_command.flags & B_RAW_DEVICE_DATA_IN)) { + /* "For various reasons Haiku return data_len - data_resid" */ + *req_dinp = ptp->data_len; + if (req_doutp) + *req_doutp = 0; + } else if (req_doutp && + !(ptp->raw_command.flags & B_RAW_DEVICE_DATA_IN)) { + *req_doutp = ptp->data_len; + if (req_dinp) + *req_dinp = 0; + } else { + if (req_dinp) + *req_dinp = 0; + if (req_doutp) + *req_doutp = 0; + } +} + +uint32_t +get_pt_result(const struct sg_pt_base * vp) +{ + return (uint32_t)get_scsi_pt_status_response(vp); +} + +uint8_t * +get_scsi_pt_cdb_buf(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return (uint8_t *)ptp->raw_command.command; +} + +int +get_scsi_pt_cdb_len(const struct sg_pt_base * vp) +{ + const struct sg_pt_haiku_scsi * ptp = &vp->impl; + + return (int)ptp->raw_command.command_length; +} + +/* Forget any previous dev_han and install the one given. May attempt to + * find file type (e.g. if pass-though) from OS so there could be an error. + * Returns 0 for success or the same value as get_scsi_pt_os_err() + * will return. dev_han should be >= 0 for a valid file handle or -1 . */ +int +set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb) +{ + struct sg_pt_haiku_scsi * ptp = &vp->impl; + + if (vb) {} + ptp->dev_fd = (dev_han < 0) ? -1 : dev_han; + ptp->in_err = 0; + ptp->os_err = 0; + return 0; +} + +void +set_scsi_pt_transport_err(struct sg_pt_base * vp, int err) +{ + if (vp) { } + if (err) { } +} + +void +set_pt_metadata_xfer(struct sg_pt_base * vp, uint8_t * mdxferp, + uint32_t mdxfer_len, bool out_true) +{ + if (vp) { } + if (mdxferp) { } + if (mdxfer_len) { } + if (out_true) { } +} diff --git a/lib/sg_pt_osf1.c b/lib/sg_pt_osf1.c index 3296e18b..8fa5e3e3 100644 --- a/lib/sg_pt_osf1.c +++ b/lib/sg_pt_osf1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2020 Douglas Gilbert. + * Copyright (c) 2005-2021 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. @@ -30,7 +30,7 @@ #include "sg_lib.h" #include "sg_pr2serr.h" -/* Version 2.03 20200722 */ +/* Version 2.04 20210617 */ #define OSF1_MAXDEV 64 @@ -660,6 +660,16 @@ check_pt_file_handle(int device_fd, const char * device_name, int vb) return 0; } +/* Valid file handles (which is the return value) are >= 0 . Returns -1 + * if there is no valid file handle. */ +int +get_pt_file_handle(const struct sg_pt_base * vp) +{ + const struct sg_pt_osf1_scsi * ptp = &vp->impl; + + return ptp->dev_fd; +} + /* If a NVMe block device (which includes the NSID) handle is associated * with 'vp', then its NSID is returned (values range from 0x1 to * 0xffffffe). Otherwise 0 is returned. */ @@ -676,3 +686,37 @@ get_pt_result(const struct sg_pt_base * vp) if (vp) { } return 0; } + +/* Forget any previous dev_han and install the one given. May attempt to + * find file type (e.g. if pass-though) from OS so there could be an error. + * Returns 0 for success or the same value as get_scsi_pt_os_err() + * will return. dev_han should be >= 0 for a valid file handle or -1 . */ +int +set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb) +{ + struct sg_pt_osf1_scsi * ptp = &vp->impl; + + if (vb) {} + ptp->dev_fd = (dev_han < 0) ? -1 : dev_han; + ptp->in_err = 0; + ptp->os_err = 0; + ptp->is_nvme = false; + return 0; +} + +void +set_scsi_pt_transport_err(struct sg_pt_base * vp, int err) +{ + if (vp) { } + if (err) { } +} + +void +set_pt_metadata_xfer(struct sg_pt_base * vp, uint8_t * mdxferp, + uint32_t mdxfer_len, bool out_true) +{ + if (vp) { } + if (mdxferp) { } + if (mdxfer_len) { } + if (out_true) { } +} diff --git a/lib/sg_pt_solaris.c b/lib/sg_pt_solaris.c index 2e5b430d..e6cfa575 100644 --- a/lib/sg_pt_solaris.c +++ b/lib/sg_pt_solaris.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2020 Douglas Gilbert. + * Copyright (c) 2007-2021 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. @@ -7,7 +7,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -/* sg_pt_solaris version 1.14 20200724 */ +/* sg_pt_solaris version 1.15 20210617 */ #include <stdio.h> #include <stdlib.h> @@ -539,6 +539,17 @@ check_pt_file_handle(int device_fd, const char * device_name, int vb) return 0; } +/* Valid file handles (which is the return value) are >= 0 . Returns -1 + * if there is no valid file handle. */ +int +get_pt_file_handle(const struct sg_pt_base * vp) +{ + const struct sg_pt_solaris_scsi * ptp = &vp->impl; + + return ptp->dev_fd; +} + + /* If a NVMe block device (which includes the NSID) handle is associated * with 'vp', then its NSID is returned (values range from 0x1 to * 0xffffffe). Otherwise 0 is returned. */ @@ -548,3 +559,20 @@ get_pt_nvme_nsid(const struct sg_pt_base * vp) if (vp) { } return 0; } + +/* Forget any previous dev_han and install the one given. May attempt to + * find file type (e.g. if pass-though) from OS so there could be an error. + * Returns 0 for success or the same value as get_scsi_pt_os_err() + * will return. dev_han should be >= 0 for a valid file handle or -1 . */ +int +set_pt_file_handle(struct sg_pt_base * vp, int dev_han, int vb) +{ + struct sg_pt_solaris_scsi * ptp = &vp->impl; + + if (vb) {} + ptp->dev_fd = (dev_han < 0) ? -1 : dev_han; + ptp->in_err = 0; + ptp->os_err = 0; + ptp->is_nvme = false; + return 0; +} |