summaryrefslogtreecommitdiff
path: root/usr/src/lib/scsi/plugins/smp
diff options
context:
space:
mode:
authorHyon Kim <Hyon.Kim@Sun.COM>2010-04-11 11:20:12 -0700
committerHyon Kim <Hyon.Kim@Sun.COM>2010-04-11 11:20:12 -0700
commitac88567a7a5bb7f01cf22cf366bc9d6203e24d7a (patch)
tree9fedf1905a420a42d139cf8318d81b0f81e3d841 /usr/src/lib/scsi/plugins/smp
parent68e180930dea31f741fd809e32c371c0d73129a3 (diff)
downloadillumos-joyent-ac88567a7a5bb7f01cf22cf366bc9d6203e24d7a.tar.gz
PSARC/2009/019 SAS Management Protocol library
6791689 need a userland mechanism for access to smp(7D) targets 6901865 need to enumerate SAS expanders in storage enclosures 6927621 need to enumerate receptacles around SAS expanders in storage enclosures 6927623 need representation of SAS HBA receptacles in topo tree 6934815 should add scsi-device and smp-device nodes beneath hba/iport nodes in topology 6791643 libses needs to link with libumem 6791646 ses2 ucode upload should allow selection of chunk size 6791730 libscsi and friends mishandle plugin paths with multiple candidates 6831769 fmd dumps core repeatedly in libses with huge enclosure 6863967 substring and subhelp pages ignored due to length mishandling 6900516 add support for SPMS-1 rev 111 SUBCHASSIS ID 6900520 ses topo enumerator ignores some enclosures 6900856 need SES_PROP_INTERNAL workaround for X4275 6901298 libscsi should work around devices intolerant of odd INQUIRY lengths 6900822 SUN libses plugin should support FRUID page 6905410 memory handling problems in libfruraw and libnvfru 6905409 use after free in libfruraw fru_close_container()
Diffstat (limited to 'usr/src/lib/scsi/plugins/smp')
-rw-r--r--usr/src/lib/scsi/plugins/smp/Makefile34
-rw-r--r--usr/src/lib/scsi/plugins/smp/Makefile.lib83
-rw-r--r--usr/src/lib/scsi/plugins/smp/Makefile.plugin57
-rw-r--r--usr/src/lib/scsi/plugins/smp/Makefile.targ86
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/Makefile.com33
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/amd64/Makefile31
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/common/sas2.c39
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/common/sas2.h39
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/common/sas2_functions.c1066
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/i386/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/sparc/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/sas2/sparcv9/Makefile31
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/Makefile.com35
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/amd64/Makefile31
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/common/usmp.c231
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/i386/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/sparc/Makefile30
-rw-r--r--usr/src/lib/scsi/plugins/smp/usmp/sparcv9/Makefile31
20 files changed, 2007 insertions, 0 deletions
diff --git a/usr/src/lib/scsi/plugins/smp/Makefile b/usr/src/lib/scsi/plugins/smp/Makefile
new file mode 100644
index 0000000000..ee46918af4
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/Makefile
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+SUBDIRS = \
+ sas2 \
+ usmp
+
+.KEEP_STATE:
+
+.PARALLEL:
+
+include ../../Makefile.subdirs
diff --git a/usr/src/lib/scsi/plugins/smp/Makefile.lib b/usr/src/lib/scsi/plugins/smp/Makefile.lib
new file mode 100644
index 0000000000..1b44f8e4a6
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/Makefile.lib
@@ -0,0 +1,83 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+.KEEP_STATE:
+.SUFFIXES:
+
+include ../../../../../../cmd/Makefile.cmd
+include ../../../../Makefile.defs
+
+#
+# Set PROG and OBJS based on the values of MODULE and SRCS. We expect that
+# these macros to be defined by the Makefile that is including this file.
+#
+PROG = $(MODULE:%=%.so)
+YOBJS = $(YSRCS:%.y=%.o)
+OBJS = $(YOBJS) $(SRCS:%.c=%.o)
+
+#
+# A module may set DMOD and DMOD_SRCS if it has a mdb proc module.
+# DMOD, if set, must match PROG above (for mdb autoloading) so it will
+# be built in a subdirectory.
+#
+ROOTDMOD = $(DMOD:%.so=$(ROOT)/usr/lib/mdb/proc/%.so)
+ROOTDMOD64 = $(DMOD:%.so=$(ROOT)/usr/lib/mdb/proc/$(MACH64)/%.so)
+DMODPROG = $(DMOD:%=dmod/%)
+DMOD_OBJS = $(DMOD_SRCS:%.c=%.o)
+
+ROOTPLUGINDIR = $(ROOTPLUGINLIBDIR)/smp/$(PLUGINTYPE)
+ROOTPLUGINDIR64 = $(ROOTPLUGINLIBDIR)/smp/$(PLUGINTYPE)/$(MACH64)
+
+ROOTPROG = $(ROOTPLUGINDIR)/$(PROG)
+ROOTPROG64 = $(ROOTPLUGINDIR64)/$(PROG)
+
+#
+# A module can set ALIASES as a list of additional names to correspond to the
+# same library.
+#
+ROOTALIASES = $(ALIASES:%=$(ROOTPLUGINDIR)/%.so)
+ROOTALIASES64 = $(ALIASES:%=$(ROOTPLUGINDIR64)/%.so)
+
+LINTFLAGS += -mu
+LINTFILES = $(SRCS:%.c=%.ln)
+
+DMODLINTTGT = $(DMOD:%=lint_dmod)
+DMODLINTFILES = $(DMOD_SRCS:%.c=%.ln)
+
+APIMAP = ../../../../libsmp/libsmp_api.map
+
+C99MODE = $(C99_ENABLE)
+CFLAGS += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS)
+CFLAGS += -G $(XREGSFLAG)
+CFLAGS64 += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS)
+CFLAGS64 += -G $(XREGSFLAG)
+CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT
+$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
+LDFLAGS += $(ZTEXT) $(ZCOMBRELOC) $(ZIGNORE)
+
+$(PROG) := LDFLAGS += $(ZDEFS) -M$(APIMAP)
+$(PROG) := LDLIBS += -lc
+
+$(DMODPROG) := LDFLAGS += $(ZNODEFS)
diff --git a/usr/src/lib/scsi/plugins/smp/Makefile.plugin b/usr/src/lib/scsi/plugins/smp/Makefile.plugin
new file mode 100644
index 0000000000..add83a92c4
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/Makefile.plugin
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../../Makefile.defs
+
+ROOTHDRDIR = $(ROOTPLUGINHDRDIR)/smp/$(PLUGINTYPE)
+ROOTHDRS = $(HDRS:%=$(ROOTHDRDIR)/%)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+lint := TARGET= lint
+install_h:= TARGET = install_h
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRDIR) $(ROOTHDRS)
+
+check:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../../Makefile.rootdirs
+include ../../../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/Makefile.targ b/usr/src/lib/scsi/plugins/smp/Makefile.targ
new file mode 100644
index 0000000000..5aee626e08
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/Makefile.targ
@@ -0,0 +1,86 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+all: $(PROG) $(DMODPROG)
+
+.NO_PARALLEL:
+.PARALLEL: $(OBJS) $(LINTFILES) $(DMOD_OBJS) $(DMODLINTFILES)
+
+$(PROG): $(OBJS) $(APIMAP)
+ $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+ $(CTFMERGE) -L VERSION -o $@ $(OBJS)
+ $(POST_PROCESS_SO)
+
+$(DMODPROG): $(DMOD_OBJS)
+ -@mkdir -p $(@D)
+ $(LINK.c) $(DMOD_OBJS) -o $@
+ $(POST_PROCESS)
+
+%.o: %.c
+ $(COMPILE.c) $<
+ $(CTFCONVERT_O)
+
+%.o: $(SRCDIR)/%.c
+ $(COMPILE.c) $<
+ $(CTFCONVERT_O)
+
+clean:
+ $(RM) $(OBJS) $(DMOD_OBJS) $(LINTFILES) $(DMODLINTFILES) $(CLEANFILES)
+
+clobber: clean
+ $(RM) $(PROG) $(DMODPROG)
+
+%.ln: %.c
+ $(LINT.c) -c $<
+
+%.ln: $(SRCDIR)/%.c
+ $(LINT.c) -c $<
+
+lint_prog: $(LINTFILES)
+ $(LINT) $(LINTFLAGS) $(LINTFILES) $(LDLIBS)
+
+lint_dmod: $(DMODLINTFILES)
+ $(LINT) $(LINTFLAGS) $(DMODLINTFILES) $(LDLIBS)
+
+lint: lint_prog $(DMODLINTTGT)
+
+install_h:
+
+$(ROOTPLUGINDIR)/%: $(PROG)
+ $(RM) $@; $(LN) -s $< $@
+
+$(ROOTPLUGINDIR64)/%: $(PROG)
+ $(RM) $@; $(LN) -s $< $@
+
+$(ROOTPROG): $$(@D) $(PROG)
+ $(RM) $@; $(INS) -s -m 0755 -f $(@D) $(PROG)
+
+$(ROOTPROG64): $$(@D) $(PROG)
+ $(RM) $@; $(INS) -s -m 0755 -f $(@D) $(PROG)
+
+$(ROOTDMOD): $$(@D) $(DMODPROG)
+ $(RM) $@; $(INS) -s -m 0755 -f $(@D) $(DMODPROG)
+
+include ../../../../Makefile.rootdirs
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/Makefile b/usr/src/lib/scsi/plugins/smp/sas2/Makefile
new file mode 100644
index 0000000000..8ababf2063
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+HDRS =
+HDRDIR = common
+PLUGINTYPE = framework
+
+include ../Makefile.plugin
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/Makefile.com b/usr/src/lib/scsi/plugins/smp/sas2/Makefile.com
new file mode 100644
index 0000000000..6c6f48fba0
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/Makefile.com
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+MODULE = sas2
+SRCS = sas2.c \
+ sas2_functions.c
+
+SRCDIR = ../common
+PLUGINTYPE = framework
+
+include ../../Makefile.lib
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/amd64/Makefile b/usr/src/lib/scsi/plugins/smp/sas2/amd64/Makefile
new file mode 100644
index 0000000000..0a34065b01
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/amd64/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+install: all $(ROOTPROG64)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.c b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.c
new file mode 100644
index 0000000000..0874cacac5
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.c
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <scsi/libsmp.h>
+#include <scsi/libsmp_plugin.h>
+#include "sas2.h"
+
+int
+_smp_init(smp_plugin_t *pp)
+{
+ smp_plugin_config_t config = {
+ .spc_name = "SAS-2",
+ .spc_functions = sas2_functions
+ };
+
+ return (smp_plugin_register(pp, LIBSMP_PLUGIN_VERSION, &config));
+}
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.h b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.h
new file mode 100644
index 0000000000..4000725f6b
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2.h
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _SAS2_H
+#define _SAS2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern smp_function_def_t sas2_functions[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SAS2_H */
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/common/sas2_functions.c b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2_functions.c
new file mode 100644
index 0000000000..1e515746c3
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/common/sas2_functions.c
@@ -0,0 +1,1066 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/scsi/generic/commands.h>
+#include <sys/scsi/impl/commands.h>
+#include <sys/scsi/generic/smp_frames.h>
+
+#include <scsi/libsmp.h>
+#include <scsi/libsmp_plugin.h>
+#include "sas2.h"
+
+/*ARGSUSED*/
+static size_t
+sas2_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN);
+}
+
+/*ARGSUSED*/
+static off_t
+sas2_rq_dataoff(smp_action_t *ap, smp_target_t *tp)
+{
+ size_t len;
+
+ smp_action_get_request_frame(ap, NULL, &len);
+
+ if (len > SMP_REQ_MINLEN)
+ return (offsetof(smp_request_frame_t, srf_data[0]));
+
+ return (-1);
+}
+
+static void
+sas2_rq_setframe(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_request_frame_t *fp;
+ uint_t cap;
+ uint16_t change_count;
+ uint16_t *rqcc;
+ size_t rqlen, rslen;
+
+ smp_action_get_request_frame(ap, (void *)&fp, &rqlen);
+ smp_action_get_response_frame(ap, NULL, &rslen);
+ cap = smp_target_getcap(tp);
+
+ fp->srf_frame_type = SMP_FRAME_TYPE_REQUEST;
+ fp->srf_function = dp->sfd_function;
+
+ if (cap & SMP_TARGET_C_LONG_RESP) {
+ fp->srf_allocated_response_len = (rslen - SMP_RESP_MINLEN) / 4;
+ fp->srf_request_len = (rqlen - SMP_REQ_MINLEN) / 4;
+ } else {
+ fp->srf_allocated_response_len = 0;
+ fp->srf_request_len = 0;
+ }
+
+ /*
+ * If this command requires that the expected expander change count
+ * be set (as many do), we will attempt to set it based on the
+ * most recently executed command. However, if the user has set it
+ * already, we will not overwrite that setting. It is the consumer's
+ * responsibility to keep track of expander changes each time it
+ * receives a new change count in a response.
+ */
+ if (dp->sfd_flags & SMP_FD_F_NEEDS_CHANGE_COUNT) {
+ ASSERT(rqlen >= SMP_REQ_MINLEN + sizeof (uint16_t));
+ /* LINTED - alignment */
+ rqcc = (uint16_t *)(&fp->srf_data[0]);
+ if (SCSI_READ16(rqcc) == 0) {
+ change_count = smp_target_get_change_count(tp);
+ SCSI_WRITE16(rqcc, change_count);
+ }
+ }
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ smp_response_frame_t *fp;
+ size_t len;
+
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (0);
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static off_t
+sas2_rs_dataoff(smp_action_t *ap, smp_target_t *tp)
+{
+ size_t len;
+
+ smp_action_get_response_frame(ap, NULL, &len);
+
+ if (len > SMP_RESP_MINLEN)
+ return (offsetof(smp_request_frame_t, srf_data[0]));
+
+ return (-1);
+}
+
+static void
+sas2_rs_getparams(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp;
+ smp_response_frame_t *fp;
+ size_t len;
+ uint16_t change_count;
+
+ dp = smp_action_get_function_def(ap);
+
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ smp_action_set_result(ap, fp->srf_result);
+
+ if (!(dp->sfd_flags & SMP_FD_F_PROVIDES_CHANGE_COUNT))
+ return;
+
+ if (len <= SMP_RESP_MINLEN + sizeof (uint16_t))
+ return;
+
+ change_count = SCSI_READ16(&fp->srf_data[0]);
+ smp_target_set_change_count(tp, change_count);
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_general_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_REPORT_GENERAL);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, 24));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_manufacturer_info_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_REPORT_MANUFACTURER_INFO);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, 56));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_self_config_status_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_self_config_status_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_zone_perm_table_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_zone_perm_table_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_broadcast_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_broadcast_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_discover_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_discover_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_discover_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_DISCOVER);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, 48));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_error_log_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_phy_error_log_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_error_log_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_REPORT_PHY_ERROR_LOG);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, sizeof (smp_report_phy_error_log_resp_t)));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_sata_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_phy_sata_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_sata_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_REPORT_PHY_SATA);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, 52));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_route_info_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_route_info_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_route_info_rs_datalen(smp_action_t *ap, smp_target_t *tp)
+{
+ const smp_function_def_t *dp = smp_action_get_function_def(ap);
+ smp_response_frame_t *fp;
+ size_t len;
+
+ ASSERT(dp->sfd_function == SMP_FUNC_REPORT_ROUTE_INFO);
+ smp_action_get_response_frame(ap, (void **)&fp, &len);
+
+ if (len >= SMP_RESP_MINLEN)
+ len -= SMP_RESP_MINLEN;
+ else
+ return (0);
+
+ len &= ~3;
+
+ if (fp->srf_response_len == 0)
+ return (MIN(len, sizeof (smp_report_route_info_resp_t)));
+
+ return (MIN(len, 4 * (fp->srf_response_len)));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_event_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_phy_event_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_discover_list_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_discover_list_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_phy_event_list_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_report_phy_event_list_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_report_exp_route_table_list_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_exp_route_table_list_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_config_general_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_config_general_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_enable_disable_zoning_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_enable_disable_zoning_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_zoned_broadcast_rq_len(size_t user, smp_target_t *tp)
+{
+ size_t descrsz;
+
+ if (user == 0 || user > 1008) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ descrsz = P2ROUNDUP((user - 1), 4);
+
+ return (SMP_REQ_MINLEN + descrsz + sizeof (smp_zoned_broadcast_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_zone_lock_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_zone_lock_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_zone_activate_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_zone_activate_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_zone_unlock_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_zone_unlock_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_config_zone_manager_password_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_config_zone_manager_password_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_config_zone_phy_info_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user == 0 || user > 252) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_config_zone_phy_info_req_t) +
+ (user - 1) * sizeof (smp_zone_phy_config_descr_t));
+}
+
+static size_t
+sas2_config_zone_perm_table_rq_len(size_t user, smp_target_t *tp)
+{
+ uint_t cap = smp_target_getcap(tp);
+ size_t maxdescr, descrsz;
+
+ if (cap & SMP_TARGET_C_ZG_256)
+ descrsz = sizeof (smp_zone_perm_descr256_t);
+ else
+ descrsz = sizeof (smp_zone_perm_descr128_t);
+
+ maxdescr = (1020 - sizeof (smp_config_zone_perm_table_req_t)) / descrsz;
+
+ if (user == 0 || user > maxdescr) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_config_zone_perm_table_req_t) - 1 +
+ user * descrsz);
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_config_route_info_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_config_route_info_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_phy_control_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_phy_control_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_phy_test_function_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user != 0) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_phy_test_function_req_t));
+}
+
+/*ARGSUSED*/
+static size_t
+sas2_config_phy_event_rq_len(size_t user, smp_target_t *tp)
+{
+ if (user == 0 || user > 126) {
+ (void) smp_set_errno(ESMP_RANGE);
+ return (0);
+ }
+
+ return (SMP_REQ_MINLEN + sizeof (smp_config_phy_event_req_t) +
+ (user - 1) * sizeof (smp_phy_event_config_descr_t));
+}
+
+smp_function_def_t sas2_functions[] = {
+{
+ .sfd_function = SMP_FUNC_REPORT_GENERAL,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_report_general_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_MANUFACTURER_INFO,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_report_manufacturer_info_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_SELF_CONFIG_STATUS,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_self_config_status_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_ZONE_PERM_TABLE,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_zone_perm_table_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_BROADCAST,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_broadcast_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_DISCOVER,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_discover_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_discover_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_PHY_ERROR_LOG,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_phy_error_log_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_report_phy_error_log_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_PHY_SATA,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_phy_sata_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_report_phy_sata_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_ROUTE_INFO,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_route_info_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_report_route_info_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_PHY_EVENT,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_phy_event_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_DISCOVER_LIST,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_discover_list_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_PHY_EVENT_LIST,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_phy_event_list_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_PROVIDES_CHANGE_COUNT,
+ .sfd_rq_len = sas2_report_exp_route_table_list_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_GENERAL,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_general_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_ENABLE_DISABLE_ZONING,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_enable_disable_zoning_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_ZONED_BROADCAST,
+ .sfd_flags = SMP_FD_F_WRITE,
+ .sfd_rq_len = sas2_zoned_broadcast_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_ZONE_LOCK,
+ .sfd_flags = SMP_FD_F_READ | SMP_FD_F_WRITE |
+ SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_zone_lock_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_ZONE_ACTIVATE,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_zone_activate_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_ZONE_UNLOCK,
+ .sfd_flags = SMP_FD_F_WRITE,
+ .sfd_rq_len = sas2_zone_unlock_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_zone_manager_password_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_ZONE_PHY_INFO,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_zone_phy_info_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_ZONE_PERM_TABLE,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_zone_perm_table_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_ROUTE_INFO,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_route_info_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_PHY_CONTROL,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_phy_control_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_PHY_TEST_FUNCTION,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_phy_test_function_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = SMP_FUNC_CONFIG_PHY_EVENT,
+ .sfd_flags = SMP_FD_F_WRITE | SMP_FD_F_NEEDS_CHANGE_COUNT,
+ .sfd_rq_len = sas2_config_phy_event_rq_len,
+ .sfd_rq_dataoff = sas2_rq_dataoff,
+ .sfd_rq_setframe = sas2_rq_setframe,
+ .sfd_rs_datalen = sas2_rs_datalen,
+ .sfd_rs_dataoff = sas2_rs_dataoff,
+ .sfd_rs_getparams = sas2_rs_getparams
+},
+{
+ .sfd_function = -1
+}
+};
+
+/*
+ * Returns the number of bytes in the request frame, including the header
+ * and footer, for the given function and capabilities. Presently the only
+ * relevant capability is long-request, which in some cases increases the
+ * size of the request from the SAS-1 spec to that found in SAS-2.
+ *
+ * Variably-sized request frames have no default size; we return 0 in that
+ * case, which will often be interpreted by the caller as an error although
+ * in general it is not.
+ */
+size_t
+smp_default_request_len(uint_t cap, smp_function_t fn)
+{
+ switch (fn) {
+ case SMP_FUNC_REPORT_GENERAL:
+ case SMP_FUNC_REPORT_MANUFACTURER_INFO:
+ case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD:
+ return (SMP_REQ_MINLEN);
+
+ case SMP_FUNC_REPORT_SELF_CONFIG_STATUS:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_self_config_status_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_REPORT_ZONE_PERM_TABLE:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_zone_perm_table_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_REPORT_BROADCAST:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_broadcast_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_DISCOVER:
+ return (SMP_REQ_MINLEN + sizeof (smp_discover_req_t));
+ case SMP_FUNC_REPORT_PHY_ERROR_LOG:
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_phy_error_log_req_t));
+ case SMP_FUNC_REPORT_PHY_SATA:
+ return (SMP_REQ_MINLEN + sizeof (smp_report_phy_sata_req_t));
+ case SMP_FUNC_REPORT_ROUTE_INFO:
+ return (SMP_REQ_MINLEN + sizeof (smp_report_route_info_req_t));
+ case SMP_FUNC_REPORT_PHY_EVENT:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_phy_event_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_DISCOVER_LIST:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_discover_list_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_REPORT_PHY_EVENT_LIST:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_phy_event_list_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_report_exp_route_table_list_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_CONFIG_GENERAL:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_config_general_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_ENABLE_DISABLE_ZONING:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_enable_disable_zoning_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_ZONE_LOCK:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_zone_lock_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_ZONE_ACTIVATE:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_zone_activate_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_ZONE_UNLOCK:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_zone_unlock_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD:
+ if (cap & SMP_TARGET_C_LONG_RESP)
+ return (SMP_REQ_MINLEN +
+ sizeof (smp_config_zone_manager_password_req_t));
+ return (SMP_REQ_MINLEN);
+ case SMP_FUNC_CONFIG_ROUTE_INFO:
+ return (SMP_REQ_MINLEN + sizeof (smp_config_route_info_req_t));
+ case SMP_FUNC_PHY_CONTROL:
+ return (SMP_REQ_MINLEN + sizeof (smp_phy_control_req_t));
+ case SMP_FUNC_PHY_TEST_FUNCTION:
+ return (SMP_REQ_MINLEN + sizeof (smp_phy_test_function_req_t));
+
+ case SMP_FUNC_ZONED_BROADCAST:
+ case SMP_FUNC_CONFIG_ZONE_PHY_INFO:
+ case SMP_FUNC_CONFIG_ZONE_PERM_TABLE:
+ case SMP_FUNC_CONFIG_PHY_EVENT:
+ default:
+ return (0);
+ }
+}
+
+/*
+ * This is slightly different - return the length in bytes, including the
+ * header and footer, to be assumed for the response frame type if the
+ * length field is zero. Since the length field will not be zero unless the
+ * long response bit is clear or the target is buggy, we always assume that
+ * the caller wants the size of the v1 frame.
+ */
+/*ARGSUSED*/
+size_t
+smp_default_response_len(uint_t cap, smp_function_t fn)
+{
+ switch (fn) {
+ case SMP_FUNC_REPORT_SELF_CONFIG_STATUS:
+ case SMP_FUNC_REPORT_ZONE_PERM_TABLE:
+ case SMP_FUNC_REPORT_ZONE_MANAGER_PASSWORD:
+ case SMP_FUNC_REPORT_BROADCAST:
+ case SMP_FUNC_REPORT_PHY_EVENT:
+ case SMP_FUNC_DISCOVER_LIST:
+ case SMP_FUNC_REPORT_PHY_EVENT_LIST:
+ case SMP_FUNC_REPORT_EXP_ROUTE_TABLE_LIST:
+ case SMP_FUNC_CONFIG_GENERAL:
+ case SMP_FUNC_ENABLE_DISABLE_ZONING:
+ case SMP_FUNC_ZONED_BROADCAST:
+ case SMP_FUNC_ZONE_LOCK:
+ case SMP_FUNC_ZONE_ACTIVATE:
+ case SMP_FUNC_ZONE_UNLOCK:
+ case SMP_FUNC_CONFIG_ZONE_MANAGER_PASSWORD:
+ case SMP_FUNC_CONFIG_ZONE_PHY_INFO:
+ case SMP_FUNC_CONFIG_ZONE_PERM_TABLE:
+ case SMP_FUNC_CONFIG_ROUTE_INFO:
+ case SMP_FUNC_PHY_CONTROL:
+ case SMP_FUNC_PHY_TEST_FUNCTION:
+ case SMP_FUNC_CONFIG_PHY_EVENT:
+ return (SMP_RESP_MINLEN);
+
+ case SMP_FUNC_REPORT_GENERAL:
+ return (SMP_RESP_MINLEN + 24);
+ case SMP_FUNC_REPORT_MANUFACTURER_INFO:
+ return (SMP_RESP_MINLEN +
+ sizeof (smp_report_manufacturer_info_resp_t));
+ case SMP_FUNC_DISCOVER:
+ return (SMP_RESP_MINLEN + 48);
+ case SMP_FUNC_REPORT_PHY_ERROR_LOG:
+ return (SMP_RESP_MINLEN +
+ sizeof (smp_report_phy_error_log_resp_t));
+ case SMP_FUNC_REPORT_PHY_SATA:
+ return (SMP_RESP_MINLEN + 52);
+ case SMP_FUNC_REPORT_ROUTE_INFO:
+ return (SMP_RESP_MINLEN +
+ sizeof (smp_report_route_info_resp_t));
+
+ default:
+ return (0);
+ }
+}
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/i386/Makefile b/usr/src/lib/scsi/plugins/smp/sas2/i386/Makefile
new file mode 100644
index 0000000000..6a01a5dce1
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+
+install: all $(ROOTPROG)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/sparc/Makefile b/usr/src/lib/scsi/plugins/smp/sas2/sparc/Makefile
new file mode 100644
index 0000000000..6a01a5dce1
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+
+install: all $(ROOTPROG)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/sas2/sparcv9/Makefile b/usr/src/lib/scsi/plugins/smp/sas2/sparcv9/Makefile
new file mode 100644
index 0000000000..0a34065b01
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/sas2/sparcv9/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+install: all $(ROOTPROG64)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/Makefile b/usr/src/lib/scsi/plugins/smp/usmp/Makefile
new file mode 100644
index 0000000000..d0d0a64787
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+HDRS =
+HDRDIR = common
+PLUGINTYPE = engine
+
+include ../Makefile.plugin
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/Makefile.com b/usr/src/lib/scsi/plugins/smp/usmp/Makefile.com
new file mode 100644
index 0000000000..2c19fd0446
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/Makefile.com
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+MODULE = usmp
+SRCS = usmp.c
+
+SRCDIR = ../common
+PLUGINTYPE = engine
+
+include ../../Makefile.lib
+
+LDLIBS += -ldevinfo \
+ -ldevid
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/amd64/Makefile b/usr/src/lib/scsi/plugins/smp/usmp/amd64/Makefile
new file mode 100644
index 0000000000..0a34065b01
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/amd64/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+install: all $(ROOTPROG64)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/common/usmp.c b/usr/src/lib/scsi/plugins/smp/usmp/common/usmp.c
new file mode 100644
index 0000000000..fa3ea08921
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/common/usmp.c
@@ -0,0 +1,231 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/scsi/scsi_address.h>
+#include <sys/scsi/impl/usmp.h>
+#include <sys/libdevid.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include <scsi/libsmp.h>
+#include <scsi/libsmp_plugin.h>
+
+#include <libdevinfo.h>
+
+struct usmp_dev {
+ int ud_fd;
+ char *ud_dev;
+ uint64_t ud_addr;
+};
+
+struct di_walk_arg {
+ dev_t dev;
+ uint64_t addr;
+};
+
+static int
+di_walk(di_node_t node, di_minor_t minor, void *arg)
+{
+ struct di_walk_arg *wp = arg;
+ char *wwn;
+
+ if (di_minor_spectype(minor) != S_IFCHR)
+ return (DI_WALK_CONTINUE);
+
+ if (di_minor_devt(minor) == wp->dev) {
+ if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
+ SCSI_ADDR_PROP_TARGET_PORT, &wwn) != 1 &&
+ di_prop_lookup_strings(DDI_DEV_T_ANY, node,
+ "smp-wwn", &wwn) != 1)
+ return (DI_WALK_CONTINUE);
+
+ if (scsi_wwnstr_to_wwn(wwn, &wp->addr) != DDI_SUCCESS)
+ return (DI_WALK_CONTINUE);
+
+ return (DI_WALK_TERMINATE);
+ }
+
+ return (DI_WALK_CONTINUE);
+}
+
+static void *
+usmp_open(const void *target)
+{
+ struct usmp_dev *dp;
+ const char *target_name = (const char *)target;
+
+ struct stat64 st;
+ di_node_t root, smp;
+ struct di_walk_arg walk;
+
+ if ((dp = smp_zalloc(sizeof (struct usmp_dev))) == NULL)
+ return (NULL);
+
+ if ((dp->ud_dev = smp_strdup(target_name)) == NULL) {
+ smp_free(dp);
+ return (NULL);
+ }
+
+ if ((dp->ud_fd = open(target_name, O_RDONLY)) < 0) {
+ (void) smp_error(ESMP_BADTARGET,
+ "failed to open %s for reading: %s",
+ target_name, strerror(errno));
+ smp_free(dp->ud_dev);
+ smp_free(dp);
+ return (NULL);
+ }
+
+ if (fstat64(dp->ud_fd, &st) != 0) {
+ (void) smp_error(ESMP_BADTARGET,
+ "failed to stat %s: %s", target_name, strerror(errno));
+ (void) close(dp->ud_fd);
+ smp_free(dp->ud_dev);
+ smp_free(dp);
+ return (NULL);
+ }
+
+ if ((root = di_init("/", DINFOCACHE)) != DI_NODE_NIL) {
+ for (smp = di_drv_first_node("smp", root); smp != DI_NODE_NIL;
+ smp = di_drv_next_node(smp)) {
+ bzero(&walk, sizeof (walk));
+ walk.dev = st.st_rdev;
+ (void) di_walk_minor(smp, NULL, 0, &walk, di_walk);
+ if (walk.addr != 0) {
+ dp->ud_addr = walk.addr;
+ break;
+ }
+ }
+ di_fini(root);
+ }
+
+ return (dp);
+}
+
+static void
+usmp_close(void *private)
+{
+ struct usmp_dev *dp = (struct usmp_dev *)private;
+
+ if (dp == NULL)
+ return;
+
+ if (dp->ud_fd > 0)
+ (void) close(dp->ud_fd);
+
+ smp_free(dp->ud_dev);
+ smp_free(dp);
+}
+
+static int
+usmp_exec(void *private, smp_action_t *ap)
+{
+ struct usmp_dev *dp = (struct usmp_dev *)private;
+ struct usmp_cmd cmd;
+ void *req, *resp;
+ size_t reqlen, resplen;
+
+ bzero(&cmd, sizeof (cmd));
+
+ smp_action_get_request_frame(ap, &req, &reqlen);
+ smp_action_get_response_frame(ap, &resp, &resplen);
+
+ ASSERT(req != NULL);
+ ASSERT(resp != NULL);
+ ASSERT(reqlen != 0);
+ ASSERT(resplen != 0);
+
+ cmd.usmp_req = req;
+ cmd.usmp_reqsize = reqlen;
+ cmd.usmp_rsp = resp;
+ cmd.usmp_rspsize = resplen;
+ cmd.usmp_timeout = (int)smp_action_get_timeout(ap);
+
+ if (ioctl(dp->ud_fd, USMPFUNC, &cmd) < 0) {
+ ASSERT(errno != EFAULT);
+ switch (errno) {
+ case EINVAL:
+ return (smp_error(ESMP_BADFUNC, "internal usmp error"));
+ case EPERM:
+ return (smp_error(ESMP_PERM,
+ "insufficient privileges"));
+ case EIO:
+ return (smp_error(ESMP_IO, "I/O error"));
+ default:
+ return (smp_error(ESMP_SYS, "usmp ioctl failed: %s",
+ strerror(errno)));
+ }
+ }
+
+ /*
+ * There is no way to determine the amount of data actually transferred
+ * so we will just place the upper bound at the allocated size.
+ */
+ smp_action_set_response_len(ap, resplen);
+
+ return (0);
+}
+
+static void
+usmp_target_name(void *private, char *buf, size_t len)
+{
+ struct usmp_dev *dp = (struct usmp_dev *)private;
+
+ (void) strlcpy(buf, dp->ud_dev, len);
+}
+
+static uint64_t
+usmp_target_addr(void *private)
+{
+ struct usmp_dev *dp = (struct usmp_dev *)private;
+
+ return (dp->ud_addr);
+}
+
+static const smp_engine_ops_t usmp_ops = {
+ .seo_open = usmp_open,
+ .seo_close = usmp_close,
+ .seo_exec = usmp_exec,
+ .seo_target_name = usmp_target_name,
+ .seo_target_addr = usmp_target_addr
+};
+
+int
+_smp_init(smp_engine_t *ep)
+{
+ smp_engine_config_t config = {
+ .sec_name = "usmp",
+ .sec_ops = &usmp_ops
+ };
+
+ return (smp_engine_register(ep, LIBSMP_ENGINE_VERSION, &config));
+}
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/i386/Makefile b/usr/src/lib/scsi/plugins/smp/usmp/i386/Makefile
new file mode 100644
index 0000000000..6a01a5dce1
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+
+install: all $(ROOTPROG)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/sparc/Makefile b/usr/src/lib/scsi/plugins/smp/usmp/sparc/Makefile
new file mode 100644
index 0000000000..6a01a5dce1
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+
+install: all $(ROOTPROG)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/scsi/plugins/smp/usmp/sparcv9/Makefile b/usr/src/lib/scsi/plugins/smp/usmp/sparcv9/Makefile
new file mode 100644
index 0000000000..0a34065b01
--- /dev/null
+++ b/usr/src/lib/scsi/plugins/smp/usmp/sparcv9/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+install: all $(ROOTPROG64)
+
+include ../../Makefile.targ