diff options
author | Robert Mustacchi <rm@joyent.com> | 2017-05-11 20:51:16 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2017-05-23 23:41:47 +0000 |
commit | 2250f63cda40ce2b0b403556720b3513e937d810 (patch) | |
tree | d06943642ea7b669ddd9586f37c4a27089fec4bb | |
parent | 436974b4ff52a42762168eebf02f0457894b526b (diff) | |
download | illumos-joyent-2250f63cda40ce2b0b403556720b3513e937d810.tar.gz |
OS-6120 want a way to run vendor-specific commands via libscsi
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r-- | usr/src/lib/scsi/libscsi/common/libscsi.h | 5 | ||||
-rw-r--r-- | usr/src/lib/scsi/libscsi/common/scsi_engine.c | 49 | ||||
-rw-r--r-- | usr/src/lib/scsi/libscsi/libscsi_api.map | 2 | ||||
-rw-r--r-- | usr/src/lib/scsi/libscsi/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c | 4 |
5 files changed, 51 insertions, 12 deletions
diff --git a/usr/src/lib/scsi/libscsi/common/libscsi.h b/usr/src/lib/scsi/libscsi/common/libscsi.h index dea6972332..5904217fc1 100644 --- a/usr/src/lib/scsi/libscsi/common/libscsi.h +++ b/usr/src/lib/scsi/libscsi/common/libscsi.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Joyent, Inc. + * Copyright (c) 2017, Joyent, Inc. */ #ifndef _LIBSCSI_H @@ -128,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 e0e4f0a5f3..dc7a7af5c1 100644 --- a/usr/src/lib/scsi/libscsi/common/scsi_engine.c +++ b/usr/src/lib/scsi/libscsi/common/scsi_engine.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Joyent, Inc. + * Copyright (c) 2017, Joyent, Inc. */ #include <sys/types.h> @@ -266,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 @@ -470,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; /* @@ -493,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 @@ -550,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) { 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 067756f44b..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; diff --git a/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c b/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c index 6952a032ad..bd24c0fbfb 100644 --- a/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c +++ b/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c @@ -23,7 +23,7 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * Copyright 2016 Joyent, Inc. + * Copyright (c) 2017, Joyent, Inc. */ #include <sys/types.h> @@ -150,7 +150,7 @@ uscsi_exec(libscsi_hdl_t *hp, void *private, libscsi_action_t *ap) cmd.uscsi_timeout = (short)libscsi_action_get_timeout(ap); cmd.uscsi_cdb = (caddr_t)cp; - cmd.uscsi_cdblen = libscsi_cmd_cdblen(hp, *cp); + cmd.uscsi_cdblen = libscsi_action_get_cdblen(ap); if (cmd.uscsi_cdblen == 0) return (-1); |