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;
}