Print this page
OS-2444 richmond hardware maps need to support ivy bridge

@@ -70,10 +70,19 @@
 _topo_fini(topo_mod_t *mod)
 {
         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)
 {
         int fd;

@@ -86,13 +95,14 @@
         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);
                 topo_mod_dprintf(mod, "devctl open failed: %s",
                     strerror(errno));
-                return (-1);
+                return (rc);
         }
 
         if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
                 if (errno == ENOENT) {
                         /*

@@ -126,10 +136,11 @@
         nvlist_t *pargs, *nvl;
         char *driver = NULL, *devctl = NULL;
         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));
 
         if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,

@@ -195,12 +206,43 @@
                  */
                 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) {
+        /*
+         * 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;
         }