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


  57 };
  58 
  59 /*ARGSUSED*/
  60 int
  61 _topo_init(topo_mod_t *mod, topo_version_t version)
  62 {
  63         if (getenv("TOPOFACMPTSASDEBUG") != NULL)
  64                 topo_mod_setdebug(mod);
  65 
  66         return (topo_mod_register(mod, &mptsas_info, TOPO_VERSION));
  67 }
  68 
  69 void
  70 _topo_fini(topo_mod_t *mod)
  71 {
  72         topo_mod_unregister(mod);
  73 }
  74 
  75 /*
  76  * Get or set LED state for a particular target attached to an mpt_sas
  77  * instance at (Enclosure Number, Slot Number).
  78  *
  79  * Returns:
  80  *   -2  /devices node (*devctl) does not exist
  81  *   -1  All other failures
  82  *    0  Success
  83  */
  84 static int
  85 do_led_control(topo_mod_t *mod, char *devctl, uint16_t enclosure,
  86     uint16_t slot, uint8_t led, uint32_t *ledmode, boolean_t set)
  87 {
  88         int fd;
  89         mptsas_led_control_t lc;
  90 
  91         bzero(&lc, sizeof (lc));
  92 
  93         lc.Command = set ? MPTSAS_LEDCTL_FLAG_SET : MPTSAS_LEDCTL_FLAG_GET;
  94         lc.Enclosure = enclosure;
  95         lc.Slot = slot;
  96         lc.Led = led;
  97         lc.LedStatus = *ledmode;
  98 
  99         if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) {
 100                 int rc = (errno == ENOENT ? -2 : -1);
 101                 topo_mod_dprintf(mod, "devctl open failed: %s",
 102                     strerror(errno));
 103                 return (rc);

 104         }
 105 
 106         if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
 107                 if (errno == ENOENT) {
 108                         /*
 109                          * If there is not presently a target attached for
 110                          * a particular enclosure/slot pair then the driver
 111                          * does not track LED status for this bay.  Assume
 112                          * all LEDs are off.
 113                          */
 114                         lc.LedStatus = 0;
 115                 } else {

 116                         topo_mod_dprintf(mod, "led control ioctl failed: %s",
 117                             strerror(errno));
 118                         (void) close(fd);

 119                         return (-1);
 120                 }
 121         }
 122 
 123         *ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
 124 
 125         (void) close(fd);

 126         return (0);
 127 }
 128 
 129 static int
 130 mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
 131     nvlist_t *in, nvlist_t **nvout)
 132 {
 133         int err, ret = 0;
 134         tnode_t *pnode = topo_node_parent(node);
 135         uint32_t type, ledmode = 0;
 136         nvlist_t *pargs, *nvl;
 137         char *driver = NULL, *devctl = NULL;
 138         uint32_t enclosure, slot;
 139         uint8_t mptsas_led;
 140         boolean_t set;
 141         char *elem, *lastp;
 142 
 143         if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
 144                 return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
 145 
 146         if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
 147             TOPO_BINDING_DRIVER, &driver, &err) != 0 ||
 148             strcmp("mpt_sas", driver) != 0) {
 149                 topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas",
 150                     __func__);
 151                 ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
 152                 goto out;
 153         }
 154         if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
 155             &type, &err) != 0) {
 156                 topo_mod_dprintf(mod, "%s: Failed to lookup %s property "
 157                     "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err));
 158                 return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
 159         }
 160         switch (type) {


 201                 topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__,
 202                     ledmode ? "ON" : "OFF");
 203         } else {
 204                 /*
 205                  * Get the LED mode
 206                  */
 207                 set = B_FALSE;
 208                 topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
 209         }
 210 
 211         /*
 212          * devctl is a (potentially) pipe-separated list of different device
 213          * paths to try.
 214          */
 215         if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) == NULL) {
 216                 topo_mod_dprintf(mod, "%s: could not parse devctl list",
 217                     __func__);
 218                 ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 219                 goto out;
 220         }

 221         do {
 222                 topo_mod_dprintf(mod, "%s: trying mpt_sas instance at %s\n",
 223                     __func__, elem);
 224 
 225                 ret = do_led_control(mod, elem, enclosure, slot,
 226                     mptsas_led, &ledmode, set);
 227 
 228                 topo_mod_strfree(mod, elem);
 229 
 230                 /*
 231                  * Only try further devctl paths from the list if this one
 232                  * was not found:
 233                  */
 234                 if (ret != -2) {
 235                         break;
 236                 } else {
 237                         topo_mod_dprintf(mod, "%s: instance not found\n",
 238                             __func__);
 239                 }
 240 
 241         } while ((elem = topo_mod_strsplit(mod, NULL, "|", &lastp)) != NULL);



 242 
 243         if (ret != 0) {
 244                 topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
 245                 ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 246                 goto out;
 247         }
 248 
 249         if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
 250             nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
 251             nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
 252             nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
 253                 topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n",
 254                     __func__);
 255                 nvlist_free(nvl);
 256                 ret = topo_mod_seterrno(mod, EMOD_NOMEM);
 257                 goto out;
 258         }
 259         *nvout = nvl;
 260 
 261 out:




  57 };
  58 
  59 /*ARGSUSED*/
  60 int
  61 _topo_init(topo_mod_t *mod, topo_version_t version)
  62 {
  63         if (getenv("TOPOFACMPTSASDEBUG") != NULL)
  64                 topo_mod_setdebug(mod);
  65 
  66         return (topo_mod_register(mod, &mptsas_info, TOPO_VERSION));
  67 }
  68 
  69 void
  70 _topo_fini(topo_mod_t *mod)
  71 {
  72         topo_mod_unregister(mod);
  73 }
  74 
  75 /*
  76  * Get or set LED state for a particular target attached to an mpt_sas
  77  * instance at (Enclosure Number, Slot Number).  The function returns
  78  * -1 on error and sets errno to ENOENT _only_ if the /devices node
  79  *  (*devctl) does not exist.



  80  */
  81 static int
  82 do_led_control(topo_mod_t *mod, char *devctl, uint16_t enclosure,
  83     uint16_t slot, uint8_t led, uint32_t *ledmode, boolean_t set)
  84 {
  85         int fd;
  86         mptsas_led_control_t lc;
  87 
  88         bzero(&lc, sizeof (lc));
  89 
  90         lc.Command = set ? MPTSAS_LEDCTL_FLAG_SET : MPTSAS_LEDCTL_FLAG_GET;
  91         lc.Enclosure = enclosure;
  92         lc.Slot = slot;
  93         lc.Led = led;
  94         lc.LedStatus = *ledmode;
  95 
  96         if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) {
  97                 int en = errno;
  98                 topo_mod_dprintf(mod, "devctl open failed: %s",
  99                     strerror(errno));
 100                 errno = en;
 101                 return (-1);
 102         }
 103 
 104         if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) {
 105                 if (errno == ENOENT) {
 106                         /*
 107                          * If there is not presently a target attached for
 108                          * a particular enclosure/slot pair then the driver
 109                          * does not track LED status for this bay.  Assume
 110                          * all LEDs are off.
 111                          */
 112                         lc.LedStatus = 0;
 113                 } else {
 114                         int en = errno;
 115                         topo_mod_dprintf(mod, "led control ioctl failed: %s",
 116                             strerror(errno));
 117                         (void) close(fd);
 118                         errno = en;
 119                         return (-1);
 120                 }
 121         }
 122 
 123         *ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
 124 
 125         (void) close(fd);
 126         errno = 0;
 127         return (0);
 128 }
 129 
 130 static int
 131 mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
 132     nvlist_t *in, nvlist_t **nvout)
 133 {
 134         int err, ret = 0;
 135         tnode_t *pnode = topo_node_parent(node);
 136         uint32_t type, ledmode = 0;
 137         nvlist_t *pargs, *nvl;
 138         char *driver = NULL, *devctl = NULL;
 139         uint32_t enclosure, slot;
 140         uint8_t mptsas_led;
 141         boolean_t set, done;
 142         char *elem, *lastp;
 143 
 144         if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
 145                 return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
 146 
 147         if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
 148             TOPO_BINDING_DRIVER, &driver, &err) != 0 ||
 149             strcmp("mpt_sas", driver) != 0) {
 150                 topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas",
 151                     __func__);
 152                 ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
 153                 goto out;
 154         }
 155         if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
 156             &type, &err) != 0) {
 157                 topo_mod_dprintf(mod, "%s: Failed to lookup %s property "
 158                     "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err));
 159                 return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
 160         }
 161         switch (type) {


 202                 topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__,
 203                     ledmode ? "ON" : "OFF");
 204         } else {
 205                 /*
 206                  * Get the LED mode
 207                  */
 208                 set = B_FALSE;
 209                 topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
 210         }
 211 
 212         /*
 213          * devctl is a (potentially) pipe-separated list of different device
 214          * paths to try.
 215          */
 216         if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) == NULL) {
 217                 topo_mod_dprintf(mod, "%s: could not parse devctl list",
 218                     __func__);
 219                 ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 220                 goto out;
 221         }
 222         done = B_FALSE;
 223         do {
 224                 topo_mod_dprintf(mod, "%s: trying mpt_sas instance at %s\n",
 225                     __func__, elem);
 226 
 227                 ret = do_led_control(mod, elem, enclosure, slot,
 228                     mptsas_led, &ledmode, set);
 229 


 230                 /*
 231                  * Only try further devctl paths from the list if this one
 232                  * was not found:
 233                  */
 234                 if (ret == 0 || errno != ENOENT) {
 235                         done = B_TRUE;
 236                 } else {
 237                         topo_mod_dprintf(mod, "%s: instance not found\n",
 238                             __func__);
 239                 }
 240 
 241                 topo_mod_strfree(mod, elem);
 242 
 243         } while (!done && (elem = topo_mod_strsplit(mod, NULL, "|",
 244             &lastp)) != NULL);
 245 
 246         if (ret != 0) {
 247                 topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
 248                 ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
 249                 goto out;
 250         }
 251 
 252         if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
 253             nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
 254             nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
 255             nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
 256                 topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n",
 257                     __func__);
 258                 nvlist_free(nvl);
 259                 ret = topo_mod_seterrno(mod, EMOD_NOMEM);
 260                 goto out;
 261         }
 262         *nvout = nvl;
 263 
 264 out: