changeset 20579:2727d178ec5b

9821 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> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Richard Lowe <richlowe@richlowe.net>
author Robert Mustacchi <rm@joyent.com>
date Sat, 08 Sep 2018 22:39:06 +0000
parents 6e15a783e3f0
children 7acd63403bc1
files usr/src/lib/scsi/libscsi/common/libscsi.h usr/src/lib/scsi/libscsi/common/scsi_engine.c usr/src/lib/scsi/libscsi/libscsi_api.map usr/src/lib/scsi/libscsi/mapfile-vers usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c
diffstat 5 files changed, 52 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/scsi/libscsi/common/libscsi.h	Thu Jan 10 17:09:29 2019 +0200
+++ b/usr/src/lib/scsi/libscsi/common/libscsi.h	Sat Sep 08 22:39:06 2018 +0000
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc.
  */
 
 #ifndef	_LIBSCSI_H
@@ -125,8 +126,11 @@
 
 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 *);
--- a/usr/src/lib/scsi/libscsi/common/scsi_engine.c	Thu Jan 10 17:09:29 2019 +0200
+++ b/usr/src/lib/scsi/libscsi/common/scsi_engine.c	Sat Sep 08 22:39:06 2018 +0000
@@ -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 @@
 }
 
 /*
+ * 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 @@
  * 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 @@
 		    "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 @@
 	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)
 {
--- a/usr/src/lib/scsi/libscsi/libscsi_api.map	Thu Jan 10 17:09:29 2019 +0200
+++ b/usr/src/lib/scsi/libscsi/libscsi_api.map	Sat Sep 08 22:39:06 2018 +0000
@@ -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 @@
 	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 };
--- a/usr/src/lib/scsi/libscsi/mapfile-vers	Thu Jan 10 17:09:29 2019 +0200
+++ b/usr/src/lib/scsi/libscsi/mapfile-vers	Sat Sep 08 22:39:06 2018 +0000
@@ -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 @@
 		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;
--- a/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c	Thu Jan 10 17:09:29 2019 +0200
+++ b/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c	Sat Sep 08 22:39:06 2018 +0000
@@ -22,10 +22,10 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2017, Joyent, Inc.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/scsi/impl/uscsi.h>
 #include <sys/scsi/generic/commands.h>
@@ -150,7 +150,7 @@
 	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);