summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2017-05-11 20:51:16 +0000
committerRobert Mustacchi <rm@joyent.com>2017-05-23 23:41:47 +0000
commit2250f63cda40ce2b0b403556720b3513e937d810 (patch)
treed06943642ea7b669ddd9586f37c4a27089fec4bb
parent436974b4ff52a42762168eebf02f0457894b526b (diff)
downloadillumos-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.h5
-rw-r--r--usr/src/lib/scsi/libscsi/common/scsi_engine.c49
-rw-r--r--usr/src/lib/scsi/libscsi/libscsi_api.map2
-rw-r--r--usr/src/lib/scsi/libscsi/mapfile-vers3
-rw-r--r--usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c4
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);