--- old/./manifest	2013-03-14 21:02:58.658264067 +0000
+++ new/./manifest	2013-03-14 21:02:58.681547363 +0000
@@ -5333,6 +5333,7 @@
 d usr/lib/fm/topo/plugins 0755 root bin
 f usr/lib/fm/topo/plugins/disk.so 0555 root bin
 f usr/lib/fm/topo/plugins/fac_prov_ipmi.so 0555 root bin
+f usr/lib/fm/topo/plugins/fac_prov_mptsas.so 0555 root bin
 f usr/lib/fm/topo/plugins/ipmi.so 0555 root bin
 f usr/lib/fm/topo/plugins/ses.so 0555 root bin
 f usr/lib/fm/topo/plugins/xfp.so 0555 root bin
--- old/usr/src/lib/fm/topo/libtopo/common/topo_hc.h	2013-03-14 21:02:59.333955481 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/topo_hc.h	2013-03-14 21:02:59.339586899 +0000
@@ -115,6 +115,10 @@
 
 #define	TOPO_PGROUP_BINDING	"binding"
 #define	TOPO_BINDING_OCCUPANT	"occupant-path"
+#define	TOPO_BINDING_DRIVER	"driver"
+#define	TOPO_BINDING_DEVCTL	"devctl"
+#define	TOPO_BINDING_ENCLOSURE	"enclosure"
+#define	TOPO_BINDING_SLOT	"slot"
 
 #define	TOPO_PGROUP_STORAGE	"storage"
 #define	TOPO_STORAGE_INITIATOR_PORT	"initiator-port"
--- old/usr/src/lib/fm/topo/libtopo/common/topo_xml.c	2013-03-14 21:02:59.461123258 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/topo_xml.c	2013-03-14 21:02:59.466842249 +0000
@@ -1376,16 +1376,10 @@
 
 		if ((fprov = xmlGetProp(cn, (xmlChar *)Provider)) == NULL)
 			goto fenumdone;
-
-		if (xmlStrcmp(fprov, (xmlChar *)"fac_prov_ipmi") != 0) {
-			topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
-			    "Invalid provider specified: %s\n", fprov);
-			goto fenumdone;
-		}
-
 		/*
-		 * Invoke enum entry point in fac provider which will cause the
-		 * facility enumeration node method to be registered.
+		 * Invoke enum entry point in facility provider which will
+		 * cause the facility enumeration node method to be
+		 * registered.
 		 */
 		if (fac_enum_run(mp, ptn, (const char *)fprov) != 0) {
 			topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
@@ -1440,12 +1434,6 @@
 		    xmlStrcmp(ftype, (xmlChar *)Indicator) != 0)
 			goto facdone;
 
-		if (xmlStrcmp(provider, (xmlChar *)"fac_prov_ipmi") != 0) {
-			topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "fac_process: "
-			    "Invalid provider attr value: %s\n", provider);
-			goto facdone;
-		}
-
 		if ((ntn = topo_node_facbind(mp, ptn, (char *)fname,
 		    (char *)ftype)) == NULL)
 			goto facdone;
@@ -1463,8 +1451,9 @@
 			}
 		}
 		/*
-		 * Invoke enum entry point in fac_prov_ipmi module, which will
-		 * cause the provider methods to be registered on this node
+		 * Invoke enum entry point in the facility provider module,
+		 * which will cause the provider methods to be registered on
+		 * this node
 		 */
 		if (fac_enum_run(mp, ntn, (const char *)provider) != 0) {
 			topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "fac_process: "
--- old/usr/src/lib/fm/topo/modules/common/Makefile	2013-03-14 21:02:59.632141251 +0000
+++ new/usr/src/lib/fm/topo/modules/common/Makefile	2013-03-14 21:02:59.637873125 +0000
@@ -28,6 +28,7 @@
 SUBDIRS =		\
 	disk		\
 	fac_prov_ipmi	\
+	fac_prov_mptsas	\
 	ipmi		\
 	ses		\
 	xfp
--- /dev/null	2013-03-14 21:02:59.000000000 +0000
+++ new/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/Makefile	2013-03-14 21:02:59.760561803 +0000
@@ -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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# Copyright (c) 2013, Joyent, Inc. All rights reserved.
+#
+
+MODULE = fac_prov_mptsas
+CLASS = common
+
+MODULESRCS = fac_prov_mptsas.c
+
+include ../../Makefile.plugin
+
+CPPFLAGS += -I$(SRC)/uts/common
--- /dev/null	2013-03-14 21:02:59.000000000 +0000
+++ new/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c	2013-03-14 21:02:59.821527686 +0000
@@ -0,0 +1,244 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <limits.h>
+#include <alloca.h>
+#include <errno.h>
+#include <libnvpair.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/fm/protocol.h>
+#include <fm/libtopo.h>
+#include <fm/topo_mod.h>
+
+#include "sys/scsi/adapters/mpt_sas/mptsas_ioctl.h"
+
+#define	TOPO_METH_MPTSAS_LED_MODE_VERSION	0
+
+static int fac_prov_mptsas_enum(topo_mod_t *, tnode_t *, const char *,
+    topo_instance_t, topo_instance_t, void *, void *);
+
+/*
+ * mpt_sas facility provider methods
+ */
+static int mptsas_led_mode(topo_mod_t *, tnode_t *, topo_version_t,
+    nvlist_t *, nvlist_t **);
+
+const topo_modops_t mptsas_ops = { fac_prov_mptsas_enum, NULL };
+
+const topo_modinfo_t mptsas_info =
+	{ "mpt_sas facility provider", FM_FMRI_SCHEME_HC, TOPO_VERSION,
+	&mptsas_ops };
+
+static const topo_method_t mptsas_fac_methods[] = {
+	{ "mptsas_led_mode", TOPO_PROP_METH_DESC,
+	    TOPO_METH_MPTSAS_LED_MODE_VERSION,
+	    TOPO_STABILITY_INTERNAL, mptsas_led_mode },
+	{ NULL }
+};
+
+/*ARGSUSED*/
+int
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+	if (getenv("TOPOFACMPTSASDEBUG") != NULL)
+		topo_mod_setdebug(mod);
+
+	return (topo_mod_register(mod, &mptsas_info, TOPO_VERSION));
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+	topo_mod_unregister(mod);
+}
+
+static int
+do_led_control(topo_mod_t *mod, char *devctl, uint16_t enclosure,
+    uint16_t slot, uint8_t led, uint32_t *ledmode, boolean_t set)
+{
+	int fd;
+	mptsas_led_control_t lc;
+
+	bzero(&lc, sizeof (lc));
+
+	lc.Command = set ? MPTSAS_LEDCTL_FLAG_SET : MPTSAS_LEDCTL_FLAG_GET;
+	lc.Enclosure = enclosure;
+	lc.Slot = slot;
+	lc.Led = led;
+	lc.LedStatus = *ledmode;
+
+	if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) {
+		topo_mod_dprintf(mod, "devctl open failed: %s",
+		    strerror(errno));
+		return (-1);
+	}
+
+	if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
+		if (errno == ENOENT) {
+			/*
+			 * If there is not presently a target attached for
+			 * a particular enclosure/slot pair then the driver
+			 * does not track LED status for this bay.  Assume
+			 * all LEDs are off.
+			 */
+			lc.LedStatus = 0;
+		} else {
+			topo_mod_dprintf(mod, "led control ioctl failed: %s",
+			    strerror(errno));
+			(void) close(fd);
+			return (-1);
+		}
+	}
+
+	*ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
+
+	(void) close(fd);
+	return (0);
+}
+
+static int
+mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+    nvlist_t *in, nvlist_t **nvout)
+{
+	int err, ret = 0;
+	tnode_t *pnode = topo_node_parent(node);
+	uint32_t type, ledmode = 0;
+	nvlist_t *pargs, *nvl;
+	char *driver = NULL, *devctl = NULL;
+	uint32_t enclosure, slot;
+	uint8_t mptsas_led;
+	boolean_t set;
+
+	if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
+		return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
+	    TOPO_BINDING_DRIVER, &driver, &err) != 0 ||
+	    strcmp("mpt_sas", driver) != 0) {
+		topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas",
+		    __func__);
+		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
+		goto out;
+	}
+	if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
+	    &type, &err) != 0) {
+		topo_mod_dprintf(mod, "%s: Failed to lookup %s property "
+		    "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err));
+		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+	}
+	switch (type) {
+	case (TOPO_LED_TYPE_SERVICE):
+		mptsas_led = MPTSAS_LEDCTL_LED_FAIL;
+		break;
+	case (TOPO_LED_TYPE_LOCATE):
+		mptsas_led = MPTSAS_LEDCTL_LED_IDENT;
+		break;
+	case (TOPO_LED_TYPE_OK2RM):
+		mptsas_led = MPTSAS_LEDCTL_LED_OK2RM;
+		break;
+	default:
+		topo_mod_dprintf(mod, "%s: Invalid LED type: 0x%x\n", __func__,
+		    type);
+		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+	}
+	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
+	    TOPO_BINDING_DEVCTL, &devctl, &err) != 0 ||
+	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
+	    TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 ||
+	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
+	    TOPO_BINDING_SLOT, &slot, &err) != 0) {
+		topo_mod_dprintf(mod, "%s: Facility was missing mpt_sas binding"
+		    " properties\n", __func__);
+		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
+		goto out;
+	}
+
+	if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
+	    nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
+		/*
+		 * Set the LED mode
+		 */
+		set = B_TRUE;
+		if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
+		    &ledmode)) != 0) {
+			topo_mod_dprintf(mod, "%s: Failed to lookup %s nvpair "
+			    "(%s)\n", __func__, TOPO_PROP_VAL_VAL,
+			    strerror(ret));
+			ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
+			goto out;
+		}
+		topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__,
+		    ledmode ? "ON" : "OFF");
+	} else {
+		/*
+		 * Get the LED mode
+		 */
+		set = B_FALSE;
+		topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
+	}
+
+	if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode,
+	    set) != 0) {
+		topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
+		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
+		goto out;
+	}
+
+	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+	    nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
+	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
+	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
+		topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n",
+		    __func__);
+		nvlist_free(nvl);
+		ret = topo_mod_seterrno(mod, EMOD_NOMEM);
+		goto out;
+	}
+	*nvout = nvl;
+
+out:
+	if (driver != NULL)
+		topo_mod_strfree(mod, driver);
+	if (devctl != NULL)
+		topo_mod_strfree(mod, devctl);
+	return (ret);
+}
+
+/*ARGSUSED*/
+static int
+fac_prov_mptsas_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+    topo_instance_t min, topo_instance_t max, void *arg, void *unused)
+{
+	if (topo_node_flags(rnode) == TOPO_NODE_FACILITY) {
+		if (topo_method_register(mod, rnode, mptsas_fac_methods) != 0) {
+			topo_mod_dprintf(mod, "%s: topo_method_register() "
+			    "failed: %s", __func__, topo_mod_errmsg(mod));
+			return (-1);
+		}
+		return (0);
+	}
+
+	topo_mod_dprintf(mod, "%s: unexpected node flags %x", __func__,
+	    topo_node_flags(rnode));
+	return (-1);
+}
--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c	2013-03-14 21:02:59.890833023 +0000
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c	2013-03-14 21:02:59.910746695 +0000
@@ -371,8 +371,7 @@
     mptsas_phymask_t *phymask);
 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
     mptsas_phymask_t phymask);
-static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
-    uint32_t slotstatus);
+static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
 
 
 /*
@@ -6453,7 +6452,8 @@
 		}
 
 		mutex_enter(&mpt->m_mutex);
-		if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) {
+		ptgt->m_led_status = 0;
+		if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
 			NDBG14(("mptsas: clear LED for tgt %x failed",
 			    ptgt->m_slot_num));
 		}
@@ -11953,6 +11953,66 @@
 }
 
 static int
+led_control(mptsas_t *mpt, intptr_t data, int mode)
+{
+	int ret = 0;
+	mptsas_led_control_t lc;
+	mptsas_target_t *ptgt;
+
+	if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
+		return (EFAULT);
+	}
+
+	if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
+	     lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
+	     lc.Led < MPTSAS_LEDCTL_LED_IDENT ||
+	     lc.Led > MPTSAS_LEDCTL_LED_OK2RM ||
+	     (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
+	     lc.LedStatus != 1)) {
+		return (EINVAL);
+	}
+
+	/* Locate the target we're interrogating... */
+	mutex_enter(&mpt->m_mutex);
+	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
+	    MPTSAS_HASH_FIRST);
+	while (ptgt != NULL) {
+		if (ptgt->m_enclosure == lc.Enclosure &&
+		    ptgt->m_slot_num == lc.Slot) {
+			break;
+		}
+		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
+		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
+	}
+	if (ptgt == NULL) {
+		/* We could not find a target for that enclosure/slot. */
+		mutex_exit(&mpt->m_mutex);
+		return (ENOENT);
+	}
+
+	if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
+		/* Update our internal LED state. */
+		ptgt->m_led_status &= ~(1 << (lc.Led - 1));
+		ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
+
+		/* Flush it to the controller. */
+		ret = mptsas_flush_led_status(mpt, ptgt);
+		mutex_exit(&mpt->m_mutex);
+		return (ret);
+	}
+
+	/* Return our internal LED state. */
+	lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
+	mutex_exit(&mpt->m_mutex);
+
+	if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
+		return (EFAULT);
+	}
+
+	return (0);
+}
+
+static int
 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
 {
 	int i = 0;
@@ -12129,31 +12189,14 @@
 			} else if (cmd == DEVCTL_DEVICE_OFFLINE) {
 				ptgt->m_tgt_unconfigured = 1;
 			}
-			slotstatus = 0;
-#ifdef MPTSAS_GET_LED
-			/*
-			 * The get led status can't get a valid/reasonable
-			 * state, so ignore the get led status, and write the
-			 * required value directly
-			 */
-			if (mptsas_get_led_status(mpt, ptgt, &slotstatus) !=
-			    DDI_SUCCESS) {
-				NDBG14(("mptsas_ioctl: get LED for tgt %s "
-				    "failed %x", addr, slotstatus));
-				slotstatus = 0;
-			}
-			NDBG14(("mptsas_ioctl: LED status %x for %s",
-			    slotstatus, addr));
-#endif
 			if (cmd == DEVCTL_DEVICE_OFFLINE) {
-				slotstatus |=
-				    MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
+				ptgt->m_led_status |=
+				    (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
 			} else {
-				slotstatus &=
-				    ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
+				ptgt->m_led_status &=
+				    ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
 			}
-			if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
-			    DDI_SUCCESS) {
+			if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
 				NDBG14(("mptsas_ioctl: set LED for tgt %s "
 				    "failed %x", addr, slotstatus));
 			}
@@ -12166,6 +12209,9 @@
 		case MPTIOCTL_GET_DISK_INFO:
 			status = get_disk_info(mpt, data, mode);
 			break;
+		case MPTIOCTL_LED_CONTROL:
+			status = led_control(mpt, data, mode);
+			break;
 		case MPTIOCTL_UPDATE_FLASH:
 			if (ddi_copyin((void *)data, &flashdata,
 				sizeof (struct mptsas_update_flash), mode)) {
@@ -14626,8 +14672,9 @@
 				    (ptgt->m_tgt_unconfigured == 0)) {
 					rval = mdi_pi_online(*pip, 0);
 					mutex_enter(&mpt->m_mutex);
-					(void) mptsas_set_led_status(mpt, ptgt,
-					    0);
+					ptgt->m_led_status = 0;
+					(void) mptsas_flush_led_status(mpt,
+					    ptgt);
 					mutex_exit(&mpt->m_mutex);
 				} else {
 					rval = DDI_SUCCESS;
@@ -14884,8 +14931,8 @@
 		mdi_rtn = mdi_pi_online(*pip, 0);
 		if (mdi_rtn == MDI_SUCCESS) {
 			mutex_enter(&mpt->m_mutex);
-			if (mptsas_set_led_status(mpt, ptgt, 0) !=
-			    DDI_SUCCESS) {
+			ptgt->m_led_status = 0;
+			if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
 				NDBG14(("mptsas: clear LED for slot %x "
 				    "failed", ptgt->m_slot_num));
 			}
@@ -15246,8 +15293,8 @@
 		}
 		if (ndi_rtn == NDI_SUCCESS) {
 			mutex_enter(&mpt->m_mutex);
-			if (mptsas_set_led_status(mpt, ptgt, 0) !=
-			    DDI_SUCCESS) {
+			ptgt->m_led_status = 0;
+			if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
 				NDBG14(("mptsas: clear LED for tgt %x "
 				    "failed", ptgt->m_slot_num));
 			}
@@ -16148,23 +16195,26 @@
 	return (ptgt);
 }
 
-#ifdef MPTSAS_GET_LED
 static int
-mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
-    uint32_t *slotstatus)
-{
-	return (mptsas_send_sep(mpt, ptgt, slotstatus,
-	    MPI2_SEP_REQ_ACTION_READ_STATUS));
-}
-#endif
-static int
-mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus)
+mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
 {
+	uint32_t slotstatus = 0;
+
+	/* Build an MPI2 Slot Status based on our view of the world */
+	if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
+		slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
+	if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
+		slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
+	if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
+		slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
+
+	/* Write it to the controller */
 	NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
 	    slotstatus, ptgt->m_slot_num));
 	return (mptsas_send_sep(mpt, ptgt, &slotstatus,
 	    MPI2_SEP_REQ_ACTION_WRITE_STATUS));
 }
+
 /*
  *  send sep request, use enclosure/slot addressing
  */
--- old/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_ioctl.h	2013-03-14 21:03:00.418593864 +0000
+++ new/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_ioctl.h	2013-03-14 21:03:00.424449227 +0000
@@ -75,6 +75,7 @@
 #define	MPTIOCTL_DIAG_ACTION		(MPTIOCTL | 9)
 #define	MPTIOCTL_REG_ACCESS		(MPTIOCTL | 10)
 #define	MPTIOCTL_GET_DISK_INFO		(MPTIOCTL | 11)
+#define	MPTIOCTL_LED_CONTROL		(MPTIOCTL | 12)
 
 /*
  *  The following are our ioctl() return status values.  If everything went
@@ -329,6 +330,26 @@
 
 #endif /* _KERNEL */
 
+/*
+ * LED Control
+ */
+
+typedef struct mptsas_led_control
+{
+	uint8_t		Command;
+	uint16_t	Enclosure;
+	uint16_t	Slot;
+	uint8_t		Led;
+	uint8_t		LedStatus;
+} mptsas_led_control_t;
+
+#define	MPTSAS_LEDCTL_FLAG_SET		1
+#define	MPTSAS_LEDCTL_FLAG_GET		2
+
+#define	MPTSAS_LEDCTL_LED_IDENT		1
+#define	MPTSAS_LEDCTL_LED_FAIL		2
+#define	MPTSAS_LEDCTL_LED_OK2RM		3
+
 #ifdef  __cplusplus
 }
 #endif
--- old/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h	2013-03-14 21:03:00.550162240 +0000
+++ new/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h	2013-03-14 21:03:00.555817784 +0000
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 /*
@@ -208,6 +209,7 @@
 		uint16_t		m_enclosure;
 		uint16_t		m_slot_num;
 		uint32_t		m_tgt_unconfigured;
+		uint8_t			m_led_status;
 
 		/*
 		 * For the common case, the elements in this structure are
