diff options
Diffstat (limited to 'usr/src/lib/scsi/libscsi')
| -rw-r--r-- | usr/src/lib/scsi/libscsi/common/libscsi.h | 6 | ||||
| -rw-r--r-- | usr/src/lib/scsi/libscsi/common/scsi_engine.c | 61 | ||||
| -rw-r--r-- | usr/src/lib/scsi/libscsi/libscsi_api.map | 2 | ||||
| -rw-r--r-- | usr/src/lib/scsi/libscsi/mapfile-vers | 4 |
4 files changed, 65 insertions, 8 deletions
diff --git a/usr/src/lib/scsi/libscsi/common/libscsi.h b/usr/src/lib/scsi/libscsi/common/libscsi.h index 4d57d1299c..5904217fc1 100644 --- a/usr/src/lib/scsi/libscsi/common/libscsi.h +++ b/usr/src/lib/scsi/libscsi/common/libscsi.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #ifndef _LIBSCSI_H @@ -97,6 +98,7 @@ typedef struct libscsi_engine_ops { void (*lseo_close)(libscsi_hdl_t *, void *); int (*lseo_exec)(libscsi_hdl_t *, void *, libscsi_action_t *); void (*lseo_target_name)(libscsi_hdl_t *, void *, char *, size_t); + int (*lseo_max_transfer)(libscsi_hdl_t *, void *, size_t *); } libscsi_engine_ops_t; typedef struct libscsi_engine { @@ -116,6 +118,7 @@ extern libscsi_hdl_t *libscsi_get_handle(libscsi_target_t *); extern const char *libscsi_vendor(libscsi_target_t *); extern const char *libscsi_product(libscsi_target_t *); extern const char *libscsi_revision(libscsi_target_t *); +extern int libscsi_max_transfer(libscsi_target_t *, size_t *); extern libscsi_errno_t libscsi_errno(libscsi_hdl_t *); extern const char *libscsi_errmsg(libscsi_hdl_t *); @@ -125,8 +128,11 @@ extern libscsi_errno_t libscsi_errcode(const char *); extern libscsi_action_t *libscsi_action_alloc(libscsi_hdl_t *, spc3_cmd_t, uint_t, void *, size_t); +extern libscsi_action_t *libscsi_action_alloc_vendor(libscsi_hdl_t *, + spc3_cmd_t, size_t, uint_t, void *, size_t); extern sam4_status_t libscsi_action_get_status(const libscsi_action_t *); extern void libscsi_action_set_timeout(libscsi_action_t *, uint32_t); +extern size_t libscsi_action_get_cdblen(const libscsi_action_t *); extern uint32_t libscsi_action_get_timeout(const libscsi_action_t *); extern uint_t libscsi_action_get_flags(const libscsi_action_t *); extern uint8_t *libscsi_action_get_cdb(const libscsi_action_t *); diff --git a/usr/src/lib/scsi/libscsi/common/scsi_engine.c b/usr/src/lib/scsi/libscsi/common/scsi_engine.c index 3c6d5ecee9..dc7a7af5c1 100644 --- a/usr/src/lib/scsi/libscsi/common/scsi_engine.c +++ b/usr/src/lib/scsi/libscsi/common/scsi_engine.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #include <sys/types.h> @@ -265,6 +266,18 @@ libscsi_action_get_flags(const libscsi_action_t *ap) } /* + * Return the length of the CDB buffer associated with this action. Never + * fails. + */ +size_t +libscsi_action_get_cdblen(const libscsi_action_t *ap) +{ + const libscsi_action_impl_t *aip = (const libscsi_action_impl_t *)ap; + + return (aip->lsai_cdb_len); +} + +/* * Returns the address of the action's CDB. The CDB buffer is guaranteed to * be large enough to hold the complete CDB for the command specified when the * action was allocated. Therefore, changing the command/opcode portion of @@ -469,11 +482,11 @@ libscsi_action_set_senselen(libscsi_action_t *ap, size_t len) * If cmd is SPC3_CMD_REQUEST_SENSE, this flag must be clear. */ libscsi_action_t * -libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, - void *buf, size_t buflen) +libscsi_action_alloc_vendor(libscsi_hdl_t *hp, spc3_cmd_t cmd, size_t cdbsz, + uint_t flags, void *buf, size_t buflen) { libscsi_action_impl_t *aip; - size_t cdbsz, sz; + size_t sz; ptrdiff_t off; /* @@ -492,14 +505,14 @@ libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, "in order to use a buffer"); return (NULL); } - if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { - (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " - "flag not allowed for request sense command"); + + if (cdbsz == 0) { + (void) libscsi_error(hp, ESCSI_BADLENGTH, "the supplied CDB " + "buffer size has an invalid length, it must be non-zero."); return (NULL); } - if ((sz = cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) - return (NULL); + sz = cdbsz; /* * If the caller has asked for a buffer but has not provided one, we @@ -549,6 +562,25 @@ libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, return ((libscsi_action_t *)aip); } +libscsi_action_t * +libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, + void *buf, size_t buflen) +{ + size_t cdbsz; + + if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { + (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " + "flag not allowed for request sense command"); + return (NULL); + } + + if ((cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) + return (NULL); + + return (libscsi_action_alloc_vendor(hp, cmd, cdbsz, flags, buf, + buflen)); +} + void libscsi_action_free(libscsi_action_t *ap) { @@ -616,3 +648,16 @@ libscsi_exec(libscsi_action_t *ap, libscsi_target_t *tp) return (ret); } + +int +libscsi_max_transfer(libscsi_target_t *tp, size_t *sizep) +{ + libscsi_hdl_t *hp = tp->lst_hdl; + if (tp->lst_engine->lse_ops->lseo_max_transfer == NULL) { + return (libscsi_error(hp, ESCSI_NOTSUP, "max transfer " + "request not supported by engine")); + } + + return (tp->lst_engine->lse_ops->lseo_max_transfer(hp, tp->lst_priv, + sizep)); +} diff --git a/usr/src/lib/scsi/libscsi/libscsi_api.map b/usr/src/lib/scsi/libscsi/libscsi_api.map index 72efb3a2de..b44e80c611 100644 --- a/usr/src/lib/scsi/libscsi/libscsi_api.map +++ b/usr/src/lib/scsi/libscsi/libscsi_api.map @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # $mapfile_version 2 @@ -40,6 +41,7 @@ SYMBOL_SCOPE { libscsi_action_get_timeout { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_flags { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_cdb { TYPE = FUNCTION; FLAGS = extern }; + libscsi_action_get_cdblen { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_buffer { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_sense { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_set_status { TYPE = FUNCTION; FLAGS = extern }; diff --git a/usr/src/lib/scsi/libscsi/mapfile-vers b/usr/src/lib/scsi/libscsi/mapfile-vers index 7e0d8e251c..0b92a7412c 100644 --- a/usr/src/lib/scsi/libscsi/mapfile-vers +++ b/usr/src/lib/scsi/libscsi/mapfile-vers @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # # @@ -46,11 +47,13 @@ SYMBOL_VERSION SUNWprivate_1.1 { libscsi_open; libscsi_close; libscsi_action_alloc; + libscsi_action_alloc_vendor; libscsi_action_get_status; libscsi_action_set_status; libscsi_action_get_timeout; libscsi_action_set_timeout; libscsi_action_get_cdb; + libscsi_action_get_cdblen; libscsi_action_get_flags; libscsi_action_get_buffer; libscsi_action_get_sense; @@ -71,6 +74,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { libscsi_vendor; libscsi_product; libscsi_revision; + libscsi_max_transfer; libscsi_get_handle; libscsi_alloc; |
