--- old/usr/src/lib/fm/topo/libtopo/common/topo_string.c	2013-08-28 19:10:28.015194766 +0000
+++ new/usr/src/lib/fm/topo/libtopo/common/topo_string.c	2013-08-28 19:10:28.028087157 +0000
@@ -70,13 +70,12 @@
 		 * Start scanning at beginning of input:
 		 */
 		scanstart = input;
-	} else {
+	} else if (*lastp == NULL) {
 		/*
 		 * If we have already finished scanning, return NULL.
 		 */
-		if (*lastp == NULL)
-			return (NULL);
-
+		return (NULL);
+	} else {
 		/*
 		 * Otherwise, start scanning where we left off:
 		 */
@@ -91,7 +90,9 @@
 		 */
 		*lastp = token + seplen;
 		/*
-		 * Copy out this element:
+		 * Copy out this element.  The buffer must fit the string
+		 * exactly, so that topo_hdl_strfree() can determine its
+		 * size with strlen().
 		 */
 		ret = topo_hdl_alloc(hdl, token - scanstart + 1);
 		(void) strncpy(ret, scanstart, token - scanstart);
--- old/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c	2013-08-28 19:10:28.249193409 +0000
+++ new/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c	2013-08-28 19:10:28.259954302 +0000
@@ -34,18 +34,16 @@
 
 /*
  * 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
+ * instance at (Enclosure Number, Slot Number).  The function returns
+ * -1 on error and sets errno to ENOENT _only_ if the /devices node
+ * (*devctl) does not exist.
  */
 static int
 get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
     uint32_t slot, char **sas_address)
 {
-	int fd, err, i;
+	int ret = -1, en = ENXIO;
+	int fd, i;
 	mptsas_get_disk_info_t gdi;
 	mptsas_disk_info_t *di;
 	size_t disz;
@@ -53,17 +51,19 @@
 	bzero(&gdi, sizeof (gdi));
 
 	if ((fd = open(devctl, O_RDWR)) == -1) {
-		int rc = (errno == ENOENT ? -2 : -1);
+		en = errno;
 		topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
 		    devctl, strerror(errno));
-		return (rc);
+		errno = en;
+		return (-1);
 	}
 
 	if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
+		if (errno != ENOENT)
+			en = errno;
 		topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl,
 		    strerror(errno));
-		(void) close(fd);
-		return (-1);
+		goto out;
 	}
 
 	gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) *
@@ -71,19 +71,19 @@
 	gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz);
 	if (di == NULL) {
 		topo_mod_dprintf(mod, "memory allocation failed\n");
-		(void) close(fd);
-		return (-1);
+		en = ENOMEM;
+		goto out;
 	}
 
 	if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
+		if (errno != ENOENT)
+			en = errno;
 		topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl,
 		    strerror(errno));
 		topo_mod_free(mod, di, disz);
-		(void) close(fd);
-		return (-1);
+		goto out;
 	}
 
-	err = -1;
 	for (i = 0; i < gdi.DiskCount; i++) {
 		if (di[i].Enclosure == enclosure && di[i].Slot == slot) {
 			char sas[17]; /* 16 hex digits and NUL */
@@ -91,14 +91,16 @@
 			topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) "
 			    "with adddress %s\n", enclosure, slot, sas);
 			*sas_address = topo_mod_strdup(mod, sas);
-			err = 0;
+			en = ret = 0;
 			break;
 		}
 	}
 
 	topo_mod_free(mod, di, disz);
+out:
 	(void) close(fd);
-	return (err);
+	errno = en;
+	return (ret);
 }
 
 int
@@ -132,6 +134,7 @@
 	 * paths to try.
 	 */
 	if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) != NULL) {
+		boolean_t done = B_FALSE;
 		do {
 			topo_mod_dprintf(mod, "trying mpt_sas instance at %s\n",
 			    elem);
@@ -139,19 +142,19 @@
 			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;
+			if (ret == 0 || errno != ENOENT) {
+				done = B_TRUE;
 			} else {
 				topo_mod_dprintf(mod, "instance not found\n");
 			}
 
-		} while ((elem = topo_mod_strsplit(mod, NULL, "|",
+			topo_mod_strfree(mod, elem);
+
+		} while (!done && (elem = topo_mod_strsplit(mod, NULL, "|",
 		    &lastp)) != NULL);
 	}
 
--- old/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c	2013-08-28 19:10:28.468824446 +0000
+++ new/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c	2013-08-28 19:10:28.475671914 +0000
@@ -74,12 +74,9 @@
 
 /*
  * 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
+ * instance at (Enclosure Number, Slot Number).  The function returns
+ * -1 on error and sets errno to ENOENT _only_ if the /devices node
+ *  (*devctl) does not exist.
  */
 static int
 do_led_control(topo_mod_t *mod, char *devctl, uint16_t enclosure,
@@ -97,10 +94,11 @@
 	lc.LedStatus = *ledmode;
 
 	if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) {
-		int rc = (errno == ENOENT ? -2 : -1);
+		int en = errno;
 		topo_mod_dprintf(mod, "devctl open failed: %s",
 		    strerror(errno));
-		return (rc);
+		errno = en;
+		return (-1);
 	}
 
 	if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
@@ -113,9 +111,11 @@
 			 */
 			lc.LedStatus = 0;
 		} else {
+			int en = errno;
 			topo_mod_dprintf(mod, "led control ioctl failed: %s",
 			    strerror(errno));
 			(void) close(fd);
+			errno = en;
 			return (-1);
 		}
 	}
@@ -123,6 +123,7 @@
 	*ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
 
 	(void) close(fd);
+	errno = 0;
 	return (0);
 }
 
@@ -137,7 +138,7 @@
 	char *driver = NULL, *devctl = NULL;
 	uint32_t enclosure, slot;
 	uint8_t mptsas_led;
-	boolean_t set;
+	boolean_t set, done;
 	char *elem, *lastp;
 
 	if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
@@ -218,6 +219,7 @@
 		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 		goto out;
 	}
+	done = B_FALSE;
 	do {
 		topo_mod_dprintf(mod, "%s: trying mpt_sas instance at %s\n",
 		    __func__, elem);
@@ -225,20 +227,21 @@
 		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;
+		if (ret == 0 || errno != ENOENT) {
+			done = B_TRUE;
 		} else {
 			topo_mod_dprintf(mod, "%s: instance not found\n",
 			    __func__);
 		}
 
-	} while ((elem = topo_mod_strsplit(mod, NULL, "|", &lastp)) != NULL);
+		topo_mod_strfree(mod, elem);
+
+	} while (!done && (elem = topo_mod_strsplit(mod, NULL, "|",
+	    &lastp)) != NULL);
 
 	if (ret != 0) {
 		topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
