--- old/usr/src/lib/fm/topo/libtopo/common/libtopo.h	2013-08-26 22:30:29.916627526 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/libtopo.h	2013-08-26 22:30:29.923057555 +0000
@@ -22,6 +22,9 @@
 /*
  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #ifndef _LIBTOPO_H
 #define	_LIBTOPO_H
@@ -389,6 +392,8 @@
 extern int topo_hdl_nvalloc(topo_hdl_t *, nvlist_t **, uint_t);
 extern int topo_hdl_nvdup(topo_hdl_t *, nvlist_t *, nvlist_t **);
 extern char *topo_hdl_strdup(topo_hdl_t *, const char *);
+extern char *topo_hdl_strsplit(topo_hdl_t *, const char *, const char *,
+    char **);
 
 /*
  * Interfaces for converting sensor/indicator types, units, states, etc to
--- old/usr/src/lib/fm/topo/libtopo/common/mapfile-vers	2013-08-26 22:30:30.103625758 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/mapfile-vers	2013-08-26 22:30:30.109778034 +0000
@@ -76,6 +76,7 @@
 	topo_hdl_prominfo;
 	topo_hdl_strdup;
 	topo_hdl_strfree;
+	topo_hdl_strsplit;
 	topo_hdl_zalloc;
 	topo_led_state_name;
 	topo_led_type_name;
@@ -118,6 +119,7 @@
 	topo_mod_str2nvl;
 	topo_mod_strdup;
 	topo_mod_strfree;
+	topo_mod_strsplit;
 	topo_mod_unload;
 	topo_mod_unregister;
 	topo_mod_walk_init;
--- old/usr/src/lib/fm/topo/libtopo/common/topo_mod.h	2013-08-26 22:30:30.286827297 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/topo_mod.h	2013-08-26 22:30:30.293056924 +0000
@@ -22,6 +22,9 @@
 /*
  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #ifndef _TOPO_MOD_H
 #define	_TOPO_MOD_H
@@ -215,6 +218,8 @@
 extern void topo_mod_free(topo_mod_t *, void *, size_t);
 extern char *topo_mod_strdup(topo_mod_t *, const char *);
 extern void topo_mod_strfree(topo_mod_t *, char *);
+extern char *topo_mod_strsplit(topo_mod_t *, const char *, const char *,
+    char **);
 extern int topo_mod_nvalloc(topo_mod_t *, nvlist_t **, uint_t);
 extern int topo_mod_nvdup(topo_mod_t *, nvlist_t *, nvlist_t **);
 
--- old/usr/src/lib/fm/topo/libtopo/common/topo_string.c	2013-08-26 22:30:30.474141995 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/topo_string.c	2013-08-26 22:30:30.480220289 +0000
@@ -23,8 +23,9 @@
  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #include <strings.h>
 #include <ctype.h>
@@ -56,6 +57,57 @@
 }
 
 char *
+topo_hdl_strsplit(topo_hdl_t *hdl, const char *input, const char *sep,
+    char **lastp)
+{
+	size_t seplen = strlen(sep);
+	const char *scanstart;
+	char *token;
+	char *ret;
+
+	if (input != NULL) {
+		/*
+		 * Start scanning at beginning of input:
+		 */
+		scanstart = input;
+	} else {
+		/*
+		 * If we have already finished scanning, return NULL.
+		 */
+		if (*lastp == NULL)
+			return (NULL);
+
+		/*
+		 * Otherwise, start scanning where we left off:
+		 */
+		scanstart = *lastp;
+	}
+
+	token = strstr(scanstart, sep);
+	if (token != NULL) {
+		/*
+		 * We still have a separator, so advance the next-start
+		 * pointer past it:
+		 */
+		*lastp = token + seplen;
+		/*
+		 * Copy out this element:
+		 */
+		ret = topo_hdl_alloc(hdl, token - scanstart + 1);
+		(void) strncpy(ret, scanstart, token - scanstart);
+		ret[token - scanstart] = '\0';
+	} else {
+		/*
+		 * We have no separator, so this is the last element:
+		 */
+		*lastp = NULL;
+		ret = topo_hdl_strdup(hdl, scanstart);
+	}
+
+	return (ret);
+}
+
+char *
 topo_mod_strdup(topo_mod_t *mod, const char *s)
 {
 	return (topo_hdl_strdup(mod->tm_hdl, s));
@@ -67,6 +119,13 @@
 	topo_hdl_strfree(mod->tm_hdl, s);
 }
 
+char *
+topo_mod_strsplit(topo_mod_t *mod, const char *input, const char *sep,
+    char **lastp)
+{
+	return (topo_hdl_strsplit(mod->tm_hdl, input, sep, lastp));
+}
+
 const char *
 topo_strbasename(const char *s)
 {
--- old/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Joyent-Compute-Platform-1101-disk-hc-topology.xmlgenksh	2013-08-26 22:30:30.659905336 +0000
+++ new/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Joyent-Compute-Platform-1101-disk-hc-topology.xmlgenksh	2013-08-26 22:30:30.666884003 +0000
@@ -69,17 +69,19 @@
 enclosure=1
 bay=0
 slot=0
-devctl='/devices/pci@0,0/pci8086,3c02@1/pci15d9,691@0:devctl'
+devctl0='/devices/pci@0,0/pci8086,3c02@1/pci15d9,691@0:devctl'
+devctl1='/devices/pci@0,0/pci8086,e02@1/pci15d9,691@0:devctl'
 while (( slot <= 7 )); do
-  do_node $bay "Front Disk $bay" "$devctl" $enclosure $slot
+  do_node $bay "Front Disk $bay" "$devctl0|$devctl1" $enclosure $slot
   (( bay = bay + 1 ))
   (( slot = slot + 1 ))
 done
 
 slot=0
-devctl='/devices/pci@0,0/pci8086,3c06@2,2/pci15d9,691@0:devctl'
+devctl0='/devices/pci@0,0/pci8086,3c06@2,2/pci15d9,691@0:devctl'
+devctl1='/devices/pci@0,0/pci8086,e06@2,2/pci15d9,691@0:devctl'
 while (( slot <= 7 )); do
-  do_node $bay "Front Disk $bay" "$devctl" $enclosure $slot
+  do_node $bay "Front Disk $bay" "$devctl0|$devctl1" $enclosure $slot
   (( bay = bay + 1 ))
   (( slot = slot + 1 ))
 done
--- old/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c	2013-08-26 22:30:30.828507544 +0000
+++ new/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c	2013-08-26 22:30:30.834619412 +0000
@@ -32,6 +32,15 @@
 #include "disk.h"
 #include "disk_drivers.h"
 
+/*
+ * Request the SAS address of the disk (if any) attached to this mpt_sas
+ * instance at (Enclosure Number, Slot Number).
+ *
+ * Returns:
+ *   -2   /devices node (*devctl) does not exist
+ *   -1   All other failures
+ *    0   Success
+ */
 static int
 get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
     uint32_t slot, char **sas_address)
@@ -44,9 +53,10 @@
 	bzero(&gdi, sizeof (gdi));
 
 	if ((fd = open(devctl, O_RDWR)) == -1) {
+		int rc = (errno == ENOENT ? -2 : -1);
 		topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
 		    devctl, strerror(errno));
-		return (-1);
+		return (rc);
 	}
 
 	if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
@@ -97,6 +107,8 @@
 	char *devctl = NULL;
 	uint32_t enclosure, slot;
 	int err;
+	char *elem, *lastp;
+	int ret = -1;
 
 	/*
 	 * Get the required properties from the node.  These come from
@@ -115,6 +127,34 @@
 		return (-1);
 	}
 
-	return (get_sas_address(mod, devctl, enclosure, slot, sas_address));
+	/*
+	 * devctl is a (potentially) pipe-separated list of different device
+	 * paths to try.
+	 */
+	if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) != NULL) {
+		do {
+			topo_mod_dprintf(mod, "trying mpt_sas instance at %s\n",
+			    elem);
+
+			ret = get_sas_address(mod, elem, enclosure,
+			    slot, sas_address);
+
+			topo_mod_strfree(mod, elem);
+
+			/*
+			 * Only try further devctl paths from the list if this
+			 * one was not found:
+			 */
+			if (ret != -2) {
+				break;
+			} else {
+				topo_mod_dprintf(mod, "instance not found\n");
+			}
+
+		} while ((elem = topo_mod_strsplit(mod, NULL, "|",
+		    &lastp)) != NULL);
+	}
 
+	topo_mod_strfree(mod, devctl);
+	return (ret);
 }
--- old/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c	2013-08-26 22:30:30.984263468 +0000
+++ new/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c	2013-08-26 22:30:30.990190818 +0000
@@ -72,6 +72,15 @@
 	topo_mod_unregister(mod);
 }
 
+/*
+ * Get or set LED state for a particular target attached to an mpt_sas
+ * instance at (Enclosure Number, Slot Number).
+ *
+ * Returns:
+ *   -2  /devices node (*devctl) does not exist
+ *   -1  All other failures
+ *    0  Success
+ */
 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)
@@ -88,9 +97,10 @@
 	lc.LedStatus = *ledmode;
 
 	if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) {
+		int rc = (errno == ENOENT ? -2 : -1);
 		topo_mod_dprintf(mod, "devctl open failed: %s",
 		    strerror(errno));
-		return (-1);
+		return (rc);
 	}
 
 	if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
@@ -128,6 +138,7 @@
 	uint32_t enclosure, slot;
 	uint8_t mptsas_led;
 	boolean_t set;
+	char *elem, *lastp;
 
 	if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
 		return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
@@ -197,8 +208,39 @@
 		topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
 	}
 
-	if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode,
-	    set) != 0) {
+	/*
+	 * devctl is a (potentially) pipe-separated list of different device
+	 * paths to try.
+	 */
+	if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) == NULL) {
+		topo_mod_dprintf(mod, "%s: could not parse devctl list",
+		    __func__);
+		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
+		goto out;
+	}
+	do {
+		topo_mod_dprintf(mod, "%s: trying mpt_sas instance at %s\n",
+		    __func__, elem);
+
+		ret = do_led_control(mod, elem, enclosure, slot,
+		    mptsas_led, &ledmode, set);
+
+		topo_mod_strfree(mod, elem);
+
+		/*
+		 * Only try further devctl paths from the list if this one
+		 * was not found:
+		 */
+		if (ret != -2) {
+			break;
+		} else {
+			topo_mod_dprintf(mod, "%s: instance not found\n",
+			    __func__);
+		}
+
+	} while ((elem = topo_mod_strsplit(mod, NULL, "|", &lastp)) != NULL);
+
+	if (ret != 0) {
 		topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
 		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 		goto out;
