Print this page
OS-2444 richmond hardware maps need to support ivy bridge (review fixes)

@@ -72,16 +72,13 @@
         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
+ * 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,
     uint16_t slot, uint8_t led, uint32_t *ledmode, boolean_t set)
 {

@@ -95,14 +92,15 @@
         lc.Slot = slot;
         lc.Led = led;
         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) {
                 if (errno == ENOENT) {
                         /*

@@ -111,20 +109,23 @@
                          * does not track LED status for this bay.  Assume
                          * all LEDs are off.
                          */
                         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);
                 }
         }
 
         *ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
 
         (void) close(fd);
+        errno = 0;
         return (0);
 }
 
 static int
 mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,

@@ -135,11 +136,11 @@
         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;
+        boolean_t set, done;
         char *elem, *lastp;
 
         if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
                 return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
 

@@ -216,31 +217,33 @@
                 topo_mod_dprintf(mod, "%s: could not parse devctl list",
                     __func__);
                 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);
 
                 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__);
                 ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
                 goto out;