Print this page
    
NEX-6238 fmtopo is not enumerating bays correctly with the HGST-1ES0034 (4U60)
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/scsi/plugins/ses/ses2/common/ses2_element.c
          +++ new/usr/src/lib/scsi/plugins/ses/ses2/common/ses2_element.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  #pragma ident   "%Z%%M% %I%     %E% SMI"
  28   28  
  29   29  #include <sys/types.h>
  30   30  #include <stddef.h>
  31   31  #include <stdio.h>
  32   32  #include <string.h>
  33   33  #include <libnvpair.h>
  34   34  
  35   35  #include <scsi/libses.h>
  36   36  #include "ses2_impl.h"
  37   37  
  38   38  static int
  39   39  elem_parse_device(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
  40   40  {
  41   41          ses2_device_status_impl_t *dip = (ses2_device_status_impl_t *)esip;
  42   42          int nverr;
  43   43  
  44   44          SES_NV_ADD(uint64, nverr, nvl, SES_DEV_PROP_SLOT_ADDR,
  45   45              dip->sdsi_slot_addr);
  46   46          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
  47   47              dip->sdsi_report);
  48   48          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
  49   49              dip->sdsi_ident);
  50   50          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, dip->sdsi_rmv);
  51   51          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
  52   52              dip->sdsi_ready_to_insert);
  53   53          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
  54   54              dip->sdsi_enclosure_bypassed_b);
  55   55          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
  56   56              dip->sdsi_enclosure_bypassed_a);
  57   57          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
  58   58              dip->sdsi_do_not_remove);
  59   59          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
  60   60              dip->sdsi_app_client_bypassed_a);
  61   61          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
  62   62              dip->sdsi_device_bypassed_b);
  63   63          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
  64   64              dip->sdsi_device_bypassed_a);
  65   65          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
  66   66              dip->sdsi_bypassed_b);
  67   67          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
  68   68              dip->sdsi_bypassed_a);
  69   69          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
  70   70              dip->sdsi_device_off);
  71   71          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
  72   72              dip->sdsi_fault_reqstd);
  73   73          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
  74   74              dip->sdsi_fault_sensed);
  75   75          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
  76   76              dip->sdsi_app_client_bypassed_b);
  77   77  
  78   78          return (0);
  79   79  }
  80   80  
  81   81  static int
  82   82  elem_parse_psu(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
  83   83  {
  84   84          ses2_psu_status_impl_t *pip = (ses2_psu_status_impl_t *)esip;
  85   85          int nverr;
  86   86  
  87   87          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
  88   88              pip->spsi_ident);
  89   89          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_CURRENT,
  90   90              pip->spsi_dc_over_current);
  91   91          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_UNDER_VOLTAGE,
  92   92              pip->spsi_dc_under_voltage);
  93   93          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_OVER_VOLTAGE,
  94   94              pip->spsi_dc_over_voltage);
  95   95          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_DC_FAIL,
  96   96              pip->spsi_dc_fail);
  97   97          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_AC_FAIL,
  98   98              pip->spsi_ac_fail);
  99   99          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_TEMP_WARN,
 100  100              pip->spsi_temp_warn);
 101  101          SES_NV_ADD(boolean_value, nverr, nvl, SES_PSU_PROP_OVERTEMP_FAIL,
 102  102              pip->spsi_overtmp_fail);
 103  103          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, pip->spsi_off);
 104  104          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
 105  105              pip->spsi_rqsted_on);
 106  106          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
 107  107          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
 108  108              pip->spsi_hot_swap);
 109  109  
 110  110          return (0);
 111  111  }
 112  112  
 113  113  static int
 114  114  elem_parse_cooling(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 115  115  {
 116  116          ses2_cooling_status_impl_t *cip = (ses2_cooling_status_impl_t *)esip;
 117  117          int nverr;
 118  118  
 119  119          SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_FAN_SPEED,
 120  120              SES2_ES_COOLING_ST_FAN_SPEED(cip));
 121  121          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 122  122              cip->scsi_ident);
 123  123          SES_NV_ADD(uint64, nverr, nvl, SES_COOLING_PROP_SPEED_CODE,
 124  124              cip->scsi_actual_speed_code);
 125  125          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF, cip->scsi_off);
 126  126          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REQUESTED_ON,
 127  127              cip->scsi_requested_on);
 128  128          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 129  129  
 130  130          return (0);
 131  131  }
 132  132  
 133  133  static int
 134  134  elem_parse_temp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 135  135  {
 136  136          ses2_temp_status_impl_t *tip = (ses2_temp_status_impl_t *)esip;
 137  137          int nverr;
 138  138  
 139  139          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, tip->stsi_ident);
 140  140          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, tip->stsi_fail);
 141  141          SES_NV_ADD(int64, nverr, nvl, SES_TEMP_PROP_TEMP,
 142  142              SES2_ES_TEMP_ST_TEMPERATURE(tip));
 143  143          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
 144  144              tip->stsi_ut_warn);
 145  145          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
 146  146              tip->stsi_ut_fail);
 147  147          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 148  148              tip->stsi_ot_warn);
 149  149          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 150  150              tip->stsi_ot_fail);
 151  151  
 152  152          return (0);
 153  153  }
 154  154  
 155  155  static int
 156  156  elem_parse_lock(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 157  157  {
 158  158          ses2_lock_status_impl_t *lip = (ses2_lock_status_impl_t *)esip;
 159  159          int nverr;
 160  160  
 161  161          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL,
 162  162              lip->slsi_fail);
 163  163          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 164  164              lip->slsi_ident);
 165  165          SES_NV_ADD(boolean_value, nverr, nvl, SES_LOCK_PROP_UNLOCKED,
 166  166              lip->slsi_unlocked);
 167  167  
 168  168          return (0);
 169  169  }
 170  170  
 171  171  static int
 172  172  elem_parse_alarm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 173  173  {
 174  174          ses2_alarm_status_impl_t *aip = (ses2_alarm_status_impl_t *)esip;
 175  175          int nverr;
 176  176  
 177  177          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, aip->sasi_fail);
 178  178          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 179  179              aip->sasi_ident);
 180  180          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_UNRECOV,
 181  181              aip->sasi_unrecov);
 182  182          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_CRIT,
 183  183              aip->sasi_crit);
 184  184          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_NONCRIT,
 185  185              aip->sasi_noncrit);
 186  186          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_INFO,
 187  187              aip->sasi_info);
 188  188          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_REMIND,
 189  189              aip->sasi_remind);
 190  190          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_MUTED,
 191  191              aip->sasi_muted);
 192  192          SES_NV_ADD(boolean_value, nverr, nvl, SES_ALARM_PROP_RQST_MUTE,
 193  193              aip->sasi_rqst_mute);
 194  194  
 195  195          return (0);
 196  196  }
 197  197  
 198  198  static int
 199  199  elem_parse_esc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 200  200  {
 201  201          ses2_controller_status_impl_t *cip =
 202  202              (ses2_controller_status_impl_t *)esip;
 203  203          int nverr;
 204  204  
 205  205          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 206  206          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
 207  207          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 208  208              cip->scsi_report);
 209  209          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_HOT_SWAP,
 210  210              cip->scsi_hot_swap);
 211  211  
 212  212          return (0);
 213  213  }
 214  214  
 215  215  static int
 216  216  elem_parse_scc(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 217  217  {
 218  218          ses2_scc_status_impl_t *sip = (ses2_scc_status_impl_t *)esip;
 219  219          int nverr;
 220  220  
 221  221          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 222  222          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 223  223          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 224  224              sip->sss_report);
 225  225  
 226  226          return (0);
 227  227  }
 228  228  
 229  229  static int
 230  230  elem_parse_cache(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 231  231  {
 232  232          ses2_nvcache_status_impl_t *np = (ses2_nvcache_status_impl_t *)esip;
 233  233          int nverr;
 234  234  
 235  235          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, np->snsi_fail);
 236  236          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 237  237              np->snsi_ident);
 238  238          SES_NV_ADD(uint64, nverr, nvl, SES_CACHE_PROP_SIZE,
 239  239              SES2_NVCACHE_SIZE(np));
 240  240  
 241  241          return (0);
 242  242  }
 243  243  
 244  244  static int
 245  245  elem_parse_ups(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 246  246  {
 247  247          ses2_ups_status_impl_t *uip = (ses2_ups_status_impl_t *)esip;
 248  248          int nverr;
 249  249  
 250  250          SES_NV_ADD(uint64, nverr, nvl, SES_UPS_PROP_TIMELEFT,
 251  251              uip->susi_battery_status);
 252  252          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_INTF_FAIL,
 253  253              uip->susi_intf_fail);
 254  254          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_WARN,
 255  255              uip->susi_warn);
 256  256          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_UPS_FAIL,
 257  257              uip->susi_ups_fail);
 258  258          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_DC_FAIL,
 259  259              uip->susi_dc_fail);
 260  260          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_FAIL,
 261  261              uip->susi_ac_fail);
 262  262          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_QUAL,
 263  263              uip->susi_ac_qual);
 264  264          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_HI,
 265  265              uip->susi_ac_hi);
 266  266          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_AC_LO,
 267  267              uip->susi_ac_lo);
 268  268          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BPF, uip->susi_bpf);
 269  269          SES_NV_ADD(boolean_value, nverr, nvl, SES_UPS_PROP_BATT_FAIL,
 270  270              uip->susi_batt_fail);
 271  271          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, uip->susi_fail);
 272  272          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, uip->susi_ident);
 273  273  
 274  274          return (0);
 275  275  }
 276  276  
 277  277  static int
 278  278  elem_parse_display(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 279  279  {
 280  280          ses2_display_status_impl_t *dip = (ses2_display_status_impl_t *)esip;
 281  281          int nverr;
 282  282  
 283  283          SES_NV_ADD(uint64, nverr, nvl, SES_DPY_PROP_MODE,
 284  284              dip->sdsi_display_mode_status);
 285  285          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, dip->sdsi_fail);
 286  286          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, dip->sdsi_ident);
 287  287          SES_NV_ADD(uint16, nverr, nvl, SES_DPY_PROP_CHAR,
 288  288              dip->sdsi_display_character_status);
 289  289  
 290  290          return (0);
 291  291  }
 292  292  
 293  293  static int
 294  294  elem_parse_keypad(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 295  295  {
 296  296          ses2_keypad_status_impl_t *kip = (ses2_keypad_status_impl_t *)esip;
 297  297          int nverr;
 298  298  
 299  299          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, kip->sksi_fail);
 300  300          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, kip->sksi_ident);
 301  301  
 302  302          return (0);
 303  303  }
 304  304  
 305  305  static int
 306  306  elem_parse_px(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 307  307  {
 308  308          ses2_port_status_impl_t *pip = (ses2_port_status_impl_t *)esip;
 309  309          int nverr;
 310  310  
 311  311          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, pip->spsi_fail);
 312  312          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, pip->spsi_ident);
 313  313          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 314  314              pip->spsi_report);
 315  315          SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_XMIT_FAIL,
 316  316              pip->spsi_xmit_fail);
 317  317          SES_NV_ADD(boolean_value, nverr, nvl, SES_PX_PROP_LOL, pip->spsi_lol);
 318  318          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 319  319              pip->spsi_disabled);
 320  320  
 321  321          return (0);
 322  322  }
 323  323  
 324  324  static int
 325  325  elem_parse_lang(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 326  326  {
 327  327          ses2_lang_status_impl_t *lip = (ses2_lang_status_impl_t *)esip;
 328  328          int nverr;
 329  329  
 330  330          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 331  331              lip->slsi_ident);
 332  332          SES_NV_ADD(uint64, nverr, nvl, SES_LANG_PROP_LANGCODE,
 333  333              SCSI_READ16(&lip->slsi_language_code));
 334  334  
 335  335          return (0);
 336  336  }
 337  337  
 338  338  static int
 339  339  elem_parse_comm(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 340  340  {
 341  341          ses2_comm_status_impl_t *cip = (ses2_comm_status_impl_t *)esip;
 342  342          int nverr;
 343  343  
 344  344          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 345  345          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 346  346              cip->scsi_ident);
 347  347          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 348  348              cip->scsi_disabled);
 349  349  
 350  350          return (0);
 351  351  }
 352  352  
 353  353  static int
 354  354  elem_parse_voltage(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 355  355  {
 356  356          ses2_voltage_status_impl_t *vip = (ses2_voltage_status_impl_t *)esip;
 357  357          int nverr;
 358  358  
 359  359          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_UNDER,
 360  360              vip->svsi_crit_under);
 361  361          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 362  362              vip->svsi_crit_over);
 363  363          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_UNDER,
 364  364              vip->svsi_warn_under);
 365  365          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 366  366              vip->svsi_warn_over);
 367  367          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, vip->svsi_fail);
 368  368          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, vip->svsi_ident);
 369  369          SES_NV_ADD(int64, nverr, nvl, SES_VS_PROP_VOLTAGE_MV,
 370  370              SCSI_READ16(&vip->svsi_voltage));
 371  371  
 372  372          return (0);
 373  373  }
 374  374  
 375  375  static int
 376  376  elem_parse_current(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 377  377  {
 378  378          ses2_current_status_impl_t *cip = (ses2_current_status_impl_t *)esip;
 379  379          int nverr;
 380  380  
 381  381          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_CRIT_OVER,
 382  382              cip->scsi_crit_over);
 383  383          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_WARN_OVER,
 384  384              cip->scsi_warn_over);
 385  385          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, cip->scsi_fail);
 386  386          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, cip->scsi_ident);
 387  387          SES_NV_ADD(int64, nverr, nvl, SES_CS_PROP_CURRENT_MA,
 388  388              SCSI_READ16(&cip->scsi_current));
 389  389  
 390  390          return (0);
 391  391  }
 392  392  
 393  393  static int
 394  394  elem_parse_itp(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 395  395  {
 396  396          ses2_itp_status_impl_t *iip = (ses2_itp_status_impl_t *)esip;
 397  397          int nverr;
 398  398  
 399  399          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, iip->sisi_fail);
 400  400          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT,
 401  401              iip->sisi_ident);
 402  402          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 403  403              iip->sisi_report);
 404  404          SES_NV_ADD(boolean_value, nverr, nvl, SES_ITP_PROP_ENABLED,
 405  405              iip->sisi_enabled);
 406  406  
 407  407          return (0);
 408  408  }
 409  409  
 410  410  static int
 411  411  elem_parse_sse(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 412  412  {
 413  413          ses2_ss_status_impl_t *sip = (ses2_ss_status_impl_t *)esip;
 414  414          int nverr;
 415  415  
 416  416          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 417  417          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 418  418          SES_NV_ADD(uint64, nverr, nvl, SES_SS_PROP_SHORT_STATUS,
 419  419              sip->sss_short_status);
 420  420  
 421  421          return (0);
 422  422  }
 423  423  
 424  424  static int
 425  425  elem_parse_arraydev(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 426  426  {
 427  427          ses2_array_device_status_impl_t *aip =
 428  428              (ses2_array_device_status_impl_t *)esip;
 429  429          int nverr;
 430  430  
 431  431          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RR_ABORT,
 432  432              aip->sadsi_rr_abort);
 433  433          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_REBUILD,
 434  434              aip->sadsi_rebuild);
 435  435          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_FAILED_ARRAY,
 436  436              aip->sadsi_in_failed_array);
 437  437          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_IN_CRIT_ARRAY,
 438  438              aip->sadsi_in_crit_array);
 439  439          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_CONS_CHK,
 440  440              aip->sadsi_cons_chk);
 441  441          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_HOT_SPARE,
 442  442              aip->sadsi_hot_spare);
 443  443          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_RSVD_DEVICE,
 444  444              aip->sadsi_rsvd_device);
 445  445          SES_NV_ADD(boolean_value, nverr, nvl, SES_AD_PROP_OK, aip->sadsi_ok);
 446  446          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_REPORT,
 447  447              aip->sadsi_report);
 448  448          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, aip->sadsi_ident);
 449  449          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_RMV, aip->sadsi_rmv);
 450  450          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_READY_TO_INSERT,
 451  451              aip->sadsi_ready_to_insert);
 452  452          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_B,
 453  453              aip->sadsi_enclosure_bypassed_b);
 454  454          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_ENC_BYP_A,
 455  455              aip->sadsi_enclosure_bypassed_a);
 456  456          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DO_NOT_REMOVE,
 457  457              aip->sadsi_do_not_remove);
 458  458          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_A,
 459  459              aip->sadsi_app_client_bypassed_a);
 460  460          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_B,
 461  461              aip->sadsi_device_bypassed_b);
 462  462          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_DEV_BYP_A,
 463  463              aip->sadsi_device_bypassed_a);
 464  464          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_B,
 465  465              aip->sadsi_bypassed_b);
 466  466          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_BYP_A,
 467  467              aip->sadsi_bypassed_a);
 468  468          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_OFF,
 469  469              aip->sadsi_device_off);
 470  470          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_RQSTD,
 471  471              aip->sadsi_fault_reqstd);
 472  472          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_FAULT_SENSED,
 473  473              aip->sadsi_fault_sensed);
 474  474          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_APP_BYP_B,
 475  475              aip->sadsi_app_client_bypassed_b);
 476  476  
 477  477          return (0);
 478  478  }
 479  479  
 480  480  static int
 481  481  elem_parse_expander(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 482  482  {
 483  483          ses2_expander_status_impl_t *eip = (ses2_expander_status_impl_t *)esip;
 484  484          int nverr;
 485  485  
 486  486          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, eip->sesi_fail);
 487  487          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, eip->sesi_ident);
 488  488  
 489  489          return (0);
 490  490  }
 491  491  
 492  492  static int
 493  493  elem_parse_sasconn(const ses2_elem_status_impl_t *esip, nvlist_t *nvl)
 494  494  {
 495  495          ses2_sasconn_status_impl_t *sip = (ses2_sasconn_status_impl_t *)esip;
 496  496          int nverr;
 497  497  
 498  498          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_FAIL, sip->sss_fail);
 499  499          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_IDENT, sip->sss_ident);
 500  500          SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_CONNECTOR_TYPE,
 501  501              sip->sss_connector_type);
 502  502          SES_NV_ADD(uint64, nverr, nvl, SES_SC_PROP_PHYSICAL_LINK,
 503  503              sip->sss_connector_physical_link);
 504  504  
 505  505          return (0);
 506  506  }
 507  507  
 508  508  static const struct status_parser {
 509  509          ses2_element_type_t type;
 510  510          int (*func)(const ses2_elem_status_impl_t *, nvlist_t *);
 511  511  } status_parsers[] = {
 512  512          { SES_ET_DEVICE, elem_parse_device },
 513  513          { SES_ET_POWER_SUPPLY, elem_parse_psu },
 514  514          { SES_ET_COOLING, elem_parse_cooling },
 515  515          { SES_ET_TEMPERATURE_SENSOR, elem_parse_temp },
 516  516          { SES_ET_DOOR_LOCK, elem_parse_lock },
 517  517          { SES_ET_AUDIBLE_ALARM, elem_parse_alarm },
 518  518          { SES_ET_ESC_ELECTRONICS, elem_parse_esc },
 519  519          { SES_ET_SCC_ELECTRONICS, elem_parse_scc },
 520  520          { SES_ET_NONVOLATILE_CACHE, elem_parse_cache },
 521  521          { SES_ET_UPS, elem_parse_ups },
 522  522          { SES_ET_DISPLAY, elem_parse_display },
 523  523          { SES_ET_KEY_PAD_ENTRY, elem_parse_keypad },
 524  524          { SES_ET_SCSI_PORT_XCVR, elem_parse_px },
 525  525          { SES_ET_LANGUAGE, elem_parse_lang },
 526  526          { SES_ET_COMMUNICATION_PORT, elem_parse_comm },
 527  527          { SES_ET_VOLTAGE_SENSOR, elem_parse_voltage },
 528  528          { SES_ET_CURRENT_SENSOR, elem_parse_current },
 529  529          { SES_ET_SCSI_TARGET_PORT, elem_parse_itp },
 530  530          { SES_ET_SCSI_INITIATOR_PORT, elem_parse_itp },
 531  531          { SES_ET_SIMPLE_SUBENCLOSURE, elem_parse_sse },
 532  532          { SES_ET_ARRAY_DEVICE, elem_parse_arraydev },
 533  533          { SES_ET_SAS_EXPANDER, elem_parse_expander },
 534  534          { SES_ET_SAS_CONNECTOR, elem_parse_sasconn },
 535  535          { (ses2_element_type_t)-1, NULL }
 536  536  };
 537  537  
 538  538  static int
 539  539  elem_parse_sd(ses_plugin_t *spp, ses_node_t *np)
 540  540  {
 541  541          ses2_elem_status_impl_t *esip;
 542  542          const struct status_parser *sp;
 543  543          nvlist_t *nvl = ses_node_props(np);
 544  544          size_t len;
 545  545          int nverr;
 546  546          uint64_t type;
 547  547  
 548  548          if ((esip = ses_plugin_page_lookup(spp,
 549  549              ses_node_snapshot(np), SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS,
 550  550              np, &len)) == NULL)
 551  551                  return (0);
 552  552  
 553  553          VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
 554  554              &type) == 0);
 555  555  
 556  556          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_STATUS_CODE,
 557  557              esip->sesi_common.sesi_status_code);
 558  558          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_SWAP,
 559  559              esip->sesi_common.sesi_swap);
 560  560          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_DISABLED,
 561  561              esip->sesi_common.sesi_disabled);
 562  562          SES_NV_ADD(boolean_value, nverr, nvl, SES_PROP_PRDFAIL,
 563  563              esip->sesi_common.sesi_prdfail);
 564  564  
 565  565          for (sp = &status_parsers[0]; sp->type != (ses2_element_type_t)-1; sp++)
 566  566                  if (sp->type == type && sp->func != NULL)
 567  567                          return (sp->func(esip, nvl));
 568  568  
 569  569          return (0);
 570  570  }
 571  571  
 572  572  static int
 573  573  elem_parse_descr(ses_plugin_t *sp, ses_node_t *np)
 574  574  {
 575  575          char *desc;
 576  576          size_t len;
 577  577          nvlist_t *props = ses_node_props(np);
 578  578          int nverr;
 579  579  
 580  580          if ((desc = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
 581  581              SES2_DIAGPAGE_ELEMENT_DESC, np, &len)) == NULL)
 582  582                  return (0);
 583  583  
 584  584          SES_NV_ADD(fixed_string, nverr, props, SES_PROP_DESCRIPTION,
 585  585              desc, len);
 586  586  
 587  587          return (0);
 588  588  }
 589  589  
 590  590  static int
 591  591  elem_parse_aes_fc(const ses2_aes_descr_fc_eip_impl_t *fp,
 592  592      nvlist_t *nvl, size_t len)
 593  593  {
 594  594          int nverr, i;
 595  595          nvlist_t **nva;
 596  596          int nports;
 597  597  
 598  598          if (len < offsetof(ses2_aes_descr_fc_eip_impl_t,
 599  599              sadfi_ports))
 600  600                  return (0);
 601  601  
 602  602          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
 603  603              fp->sadfi_bay_number);
 604  604          SES_NV_ADD(uint64, nverr, nvl, SES_FC_PROP_NODE_NAME,
 605  605              SCSI_READ64(&fp->sadfi_node_name));
 606  606  
 607  607          nports = MIN(fp->sadfi_n_ports,
 608  608              (len - offsetof(ses2_aes_descr_fc_eip_impl_t,
 609  609              sadfi_ports)) / sizeof (ses2_aes_port_descr_impl_t));
 610  610  
 611  611          if (nports == 0)
 612  612                  return (0);
 613  613  
 614  614          nva = ses_zalloc(nports * sizeof (nvlist_t *));
 615  615          if (nva == NULL)
 616  616                  return (-1);
 617  617  
 618  618          for (i = 0; i < nports; i++) {
 619  619                  if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 620  620                          goto fail;
 621  621                  if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_LOOP_POS,
 622  622                      fp->sadfi_ports[i].sapdi_port_loop_position)) != 0)
 623  623                          goto fail;
 624  624                  if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_REQ_HARDADDR,
 625  625                      fp->sadfi_ports[i].sapdi_port_requested_hard_address)) != 0)
 626  626                          goto fail;
 627  627                  nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_ID,
 628  628                      SCSI_READ24(fp->sadfi_ports[i].sapdi_n_port_identifier));
 629  629                  if (nverr != 0)
 630  630                          goto fail;
 631  631                  if ((nverr = nvlist_add_uint64(nva[i], SES_FC_PROP_N_PORT_NAME,
 632  632                      SCSI_READ64(&fp->sadfi_ports[i].sapdi_n_port_name))) != 0)
 633  633                          goto fail;
 634  634          }
 635  635  
 636  636          if ((nverr = nvlist_add_nvlist_array(nvl, SES_FC_PROP_PORTS,
 637  637              nva, nports)) != 0)
 638  638                  goto fail;
 639  639  
 640  640          for (i = 0; i < nports && nva[i] != NULL; i++)
 641  641                  nvlist_free(nva[i]);
  
    | 
      ↓ open down ↓ | 
    641 lines elided | 
    
      ↑ open up ↑ | 
  
 642  642          ses_free(nva);
 643  643          return (0);
 644  644  
 645  645  fail:
 646  646          for (i = 0; i < nports && nva[i] != NULL; i++)
 647  647                  nvlist_free(nva[i]);
 648  648          ses_free(nva);
 649  649          return (ses_set_nverrno(nverr, NULL));
 650  650  }
 651  651  
      652 +/*
      653 + * Parse the AES (0xa) SES diagnostic page.
      654 + *
      655 + * When making changes here, keep in mind that AES (re)parsing may be done by
      656 + * libses plugin(s) so it may need to be updated as well.
      657 + */
 652  658  static int
 653  659  elem_parse_aes_device(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 654  660      size_t len)
 655  661  {
 656  662          ses2_aes_descr_fc_eip_impl_t *fp;
 657  663          ses2_aes_descr_sas0_eip_impl_t *s0ep;
 658  664          ses2_aes_descr_sas0_impl_t *s0p;
 659  665          ses2_aes_descr_impl_t *dip;
 660  666          nvlist_t **nva;
 661  667          int nverr, i;
 662  668          size_t nphy;
 663  669  
 664  670          if (dep->sadei_eip) {
 665  671                  s0ep = (ses2_aes_descr_sas0_eip_impl_t *)
 666  672                      dep->sadei_protocol_specific;
 667  673                  s0p = (ses2_aes_descr_sas0_impl_t *)
 668  674                      dep->sadei_protocol_specific;
 669  675          } else {
 670  676                  dip = (ses2_aes_descr_impl_t *)dep;
 671  677                  s0ep = NULL;
 672  678                  s0p = (ses2_aes_descr_sas0_impl_t *)
 673  679                      dip->sadei_protocol_specific;
 674  680          }
 675  681  
 676  682          if (dep->sadei_invalid)
 677  683                  return (0);
 678  684  
 679  685          if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
 680  686                  fp = (ses2_aes_descr_fc_eip_impl_t *)
 681  687                      dep->sadei_protocol_specific;
 682  688  
 683  689                  if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
 684  690                          return (0);
 685  691  
 686  692                  return (elem_parse_aes_fc(fp, nvl, len -
 687  693                      offsetof(ses2_aes_descr_eip_impl_t,
 688  694                      sadei_protocol_specific)));
 689  695          } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
 690  696                  return (0);
 691  697          }
 692  698  
 693  699          if (s0p->sadsi_descriptor_type != SES2_AESD_SAS_DEVICE)
 694  700                  return (0);
 695  701  
 696  702          SES_NV_ADD(boolean_value, nverr, nvl, SES_DEV_PROP_SAS_NOT_ALL_PHYS,
 697  703              s0p->sadsi_not_all_phys);
 698  704          if (s0ep != NULL) {
 699  705                  SES_NV_ADD(uint64, nverr, nvl, SES_PROP_BAY_NUMBER,
 700  706                      s0ep->sadsi_bay_number);
 701  707                  nphy = MIN(s0ep->sadsi_n_phy_descriptors,
 702  708                      (len - offsetof(ses2_aes_descr_sas0_eip_impl_t,
 703  709                      sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
 704  710          } else {
 705  711                  nphy = MIN(s0p->sadsi_n_phy_descriptors,
 706  712                      (len - offsetof(ses2_aes_descr_sas0_impl_t,
 707  713                      sadsi_phys)) / sizeof (ses2_aes_phy0_descr_impl_t));
 708  714          }
 709  715  
 710  716          if (nphy == 0)
 711  717                  return (0);
 712  718  
 713  719          nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 714  720          if (nva == NULL)
 715  721                  return (-1);
 716  722  
 717  723          for (i = 0; i < nphy; i++) {
 718  724                  ses2_aes_phy0_descr_impl_t *pp;
 719  725                  pp = s0ep != NULL ? &s0ep->sadsi_phys[i] : &s0p->sadsi_phys[i];
 720  726                  if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 721  727                          goto fail;
 722  728                  if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_DEVICE_TYPE,
 723  729                      pp->sapdi_device_type)) != 0)
 724  730                          goto fail;
 725  731                  if ((nverr = nvlist_add_boolean_value(nva[i],
 726  732                      SES_SAS_PROP_SMPI_PORT, pp->sapdi_smp_initiator_port)) != 0)
 727  733                          goto fail;
 728  734                  if ((nverr = nvlist_add_boolean_value(nva[i],
 729  735                      SES_SAS_PROP_STPI_PORT, pp->sapdi_stp_initiator_port)) != 0)
 730  736                          goto fail;
 731  737                  if ((nverr = nvlist_add_boolean_value(nva[i],
 732  738                      SES_SAS_PROP_SSPI_PORT, pp->sapdi_ssp_initiator_port)) != 0)
 733  739                          goto fail;
 734  740                  if ((nverr = nvlist_add_boolean_value(nva[i],
 735  741                      SES_SAS_PROP_SATA_DEVICE, pp->sapdi_sata_device)) != 0)
 736  742                          goto fail;
 737  743                  if ((nverr = nvlist_add_boolean_value(nva[i],
 738  744                      SES_SAS_PROP_SMPT_PORT, pp->sapdi_smp_target_port)) != 0)
 739  745                          goto fail;
 740  746                  if ((nverr = nvlist_add_boolean_value(nva[i],
 741  747                      SES_SAS_PROP_STPT_PORT, pp->sapdi_stp_target_port)) != 0)
 742  748                          goto fail;
 743  749                  if ((nverr = nvlist_add_boolean_value(nva[i],
 744  750                      SES_SAS_PROP_SSPT_PORT, pp->sapdi_ssp_target_port)) != 0)
 745  751                          goto fail;
 746  752                  nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ATT_ADDR,
 747  753                      SCSI_READ64(&pp->sapdi_attached_sas_address));
 748  754                  if (nverr != 0)
 749  755                          goto fail;
 750  756                  nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
 751  757                      SCSI_READ64(&pp->sapdi_sas_address));
 752  758                  if (nverr != 0)
 753  759                          goto fail;
 754  760                  if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_PHY_ID,
 755  761                      pp->sapdi_phy_identifier)) != 0)
 756  762                          goto fail;
 757  763          }
 758  764  
 759  765          if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 760  766              nva, nphy)) != 0)
 761  767                  goto fail;
 762  768  
 763  769          for (i = 0; i < nphy && nva[i] != NULL; i++)
 764  770                  nvlist_free(nva[i]);
 765  771          ses_free(nva);
 766  772          return (0);
 767  773  
 768  774  fail:
 769  775          for (i = 0; i < nphy && nva[i] != NULL; i++)
 770  776                  nvlist_free(nva[i]);
 771  777          ses_free(nva);
 772  778          return (ses_set_nverrno(nverr, NULL));
 773  779  }
 774  780  
 775  781  static int
 776  782  elem_parse_aes_expander(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 777  783      size_t len)
 778  784  {
 779  785          ses2_aes_descr_exp_impl_t *sep;
 780  786          nvlist_t **nva;
 781  787          int nverr, i;
 782  788          size_t nphy;
 783  789  
 784  790          if (dep->sadei_invalid)
 785  791                  return (0);
 786  792  
 787  793          /*
 788  794           * This should never happen; no current SAS expander can have any
 789  795           * other kind of ports.  But maybe someday - one could envision a
 790  796           * SAS expander with iSCSI target ports, for example.
 791  797           */
 792  798          if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS)
 793  799                  return (0);
 794  800  
 795  801          sep = (ses2_aes_descr_exp_impl_t *)dep->sadei_protocol_specific;
 796  802          if (sep->sadei_descriptor_type != SES2_AESD_SAS_OTHER)
 797  803                  return (0);
 798  804  
 799  805          SES_NV_ADD(uint64, nverr, nvl, SES_EXP_PROP_SAS_ADDR,
 800  806              SCSI_READ64(&sep->sadei_sas_address));
 801  807  
 802  808          nphy = MIN(sep->sadei_n_exp_phy_descriptors,
 803  809              (len - offsetof(ses2_aes_descr_exp_impl_t,
 804  810              sadei_phys)) / sizeof (ses2_aes_exp_phy_descr_impl_t));
 805  811  
 806  812          if (nphy == 0)
 807  813                  return (0);
 808  814  
 809  815          nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 810  816          if (nva == NULL)
 811  817                  return (-1);
 812  818  
 813  819          for (i = 0; i < nphy; i++) {
 814  820                  if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 815  821                          goto fail;
 816  822                  if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
 817  823                      sep->sadei_phys[i].saepdi_connector_element_index)) != 0)
 818  824                          goto fail;
 819  825                  if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
 820  826                      sep->sadei_phys[i].saepdi_other_element_index)) != 0)
 821  827                          goto fail;
 822  828          }
 823  829  
 824  830          if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 825  831              nva, nphy)) != 0)
 826  832                  goto fail;
 827  833  
 828  834          for (i = 0; i < nphy && nva[i] != NULL; i++)
 829  835                  nvlist_free(nva[i]);
 830  836          ses_free(nva);
 831  837          return (0);
 832  838  
 833  839  fail:
 834  840          for (i = 0; i < nphy && nva[i] != NULL; i++)
 835  841                  nvlist_free(nva[i]);
 836  842          ses_free(nva);
 837  843          return (ses_set_nverrno(nverr, NULL));
 838  844  }
 839  845  
 840  846  static int
 841  847  elem_parse_aes_misc(const ses2_aes_descr_eip_impl_t *dep, nvlist_t *nvl,
 842  848      size_t len)
 843  849  {
 844  850          ses2_aes_descr_fc_eip_impl_t *fp;
 845  851          ses2_aes_descr_sas1_impl_t *s1p;
 846  852          nvlist_t **nva;
 847  853          int nverr, i;
 848  854          size_t nphy;
 849  855  
 850  856          if (dep->sadei_invalid)
 851  857                  return (0);
 852  858  
 853  859          if (dep->sadei_protocol_identifier == SPC4_PROTO_FIBRE_CHANNEL) {
 854  860                  fp = (ses2_aes_descr_fc_eip_impl_t *)
 855  861                      dep->sadei_protocol_specific;
 856  862  
 857  863                  if (!SES_WITHIN_PAGE_STRUCT(fp, dep, len))
 858  864                          return (0);
 859  865  
 860  866                  return (elem_parse_aes_fc(fp, nvl, len -
 861  867                      offsetof(ses2_aes_descr_eip_impl_t,
 862  868                      sadei_protocol_specific)));
 863  869          } else if (dep->sadei_protocol_identifier != SPC4_PROTO_SAS) {
 864  870                  return (0);
 865  871          }
 866  872  
 867  873          s1p = (ses2_aes_descr_sas1_impl_t *)dep->sadei_protocol_specific;
 868  874          if (s1p->sadsi_descriptor_type == SES2_AESD_SAS_DEVICE)
 869  875                  return (0);
 870  876  
 871  877          nphy = MIN(s1p->sadsi_n_phy_descriptors,
 872  878              (len - offsetof(ses2_aes_descr_sas1_impl_t,
 873  879              sadsi_phys)) / sizeof (ses2_aes_phy1_descr_impl_t));
 874  880  
 875  881          nva = ses_zalloc(nphy * sizeof (nvlist_t *));
 876  882          if (nva == NULL)
 877  883                  return (-1);
 878  884  
 879  885          for (i = 0; i < nphy; i++) {
 880  886                  if ((nverr = nvlist_alloc(&nva[i], NV_UNIQUE_NAME, 0)) != 0)
 881  887                          goto fail;
 882  888                  if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_CE_IDX,
 883  889                      s1p->sadsi_phys[i].sapdi_connector_element_index)) != 0)
 884  890                          goto fail;
 885  891                  if ((nverr = nvlist_add_uint64(nva[i], SES_PROP_OE_IDX,
 886  892                      s1p->sadsi_phys[i].sapdi_other_element_index)) != 0)
 887  893                          goto fail;
 888  894                  if ((nverr = nvlist_add_uint64(nva[i], SES_SAS_PROP_ADDR,
 889  895                      SCSI_READ64(&s1p->sadsi_phys[i].sapdi_sas_address))) != 0)
 890  896                          goto fail;
 891  897          }
 892  898  
 893  899          if ((nverr = nvlist_add_nvlist_array(nvl, SES_SAS_PROP_PHYS,
 894  900              nva, nphy)) != 0)
 895  901                  goto fail;
 896  902  
 897  903          for (i = 0; i < nphy && nva[i] != NULL; i++)
 898  904                  nvlist_free(nva[i]);
 899  905  
 900  906          ses_free(nva);
 901  907          return (0);
 902  908  
 903  909  fail:
 904  910          for (i = 0; i < nphy && nva[i] != NULL; i++)
 905  911                  nvlist_free(nva[i]);
 906  912          ses_free(nva);
 907  913          return (nverr);
 908  914  }
 909  915  
 910  916  static const struct aes_parser {
 911  917          ses2_element_type_t type;
 912  918          int (*func)(const ses2_aes_descr_eip_impl_t *, nvlist_t *, size_t);
 913  919  } aes_parsers[] = {
 914  920          { SES_ET_DEVICE, elem_parse_aes_device },
 915  921          { SES_ET_SCSI_TARGET_PORT, elem_parse_aes_misc },
 916  922          { SES_ET_SCSI_INITIATOR_PORT, elem_parse_aes_misc },
 917  923          { SES_ET_ESC_ELECTRONICS, elem_parse_aes_misc },
 918  924          { SES_ET_ARRAY_DEVICE, elem_parse_aes_device },
 919  925          { SES_ET_SAS_EXPANDER, elem_parse_aes_expander },
 920  926          { (ses2_element_type_t)-1, NULL }
 921  927  };
 922  928  
 923  929  static int
 924  930  elem_parse_aes(ses_plugin_t *sp, ses_node_t *np)
 925  931  {
 926  932          ses2_aes_descr_eip_impl_t *dep;
 927  933          nvlist_t *props = ses_node_props(np);
 928  934          const struct aes_parser *app;
 929  935          uint64_t type;
 930  936          size_t len;
 931  937  
 932  938          if (ses_node_type(np) == SES_NODE_AGGREGATE)
 933  939                  return (0);
 934  940  
 935  941          VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE,
 936  942              &type) == 0);
 937  943  
 938  944          for (app = &aes_parsers[0]; app->func != NULL; app++)
 939  945                  if (app->type == type)
 940  946                          break;
 941  947          if (app->func == NULL)
 942  948                  return (0);
 943  949  
 944  950          if ((dep = ses_plugin_page_lookup(sp, ses_node_snapshot(np),
 945  951              SES2_DIAGPAGE_ADDL_ELEM_STATUS, np, &len)) == NULL)
 946  952                  return (0);
 947  953  
 948  954          return (app->func(dep, props, len));
 949  955  }
 950  956  
 951  957  static int
 952  958  elem_parse_threshold(ses_plugin_t *sp, ses_node_t *np)
 953  959  {
 954  960          ses_snap_t *snap = ses_node_snapshot(np);
 955  961          ses2_threshold_impl_t *tp;
 956  962          nvlist_t *nvl = ses_node_props(np);
 957  963          int nverr;
 958  964          uint64_t type;
 959  965          size_t len;
 960  966  
 961  967          VERIFY(nvlist_lookup_uint64(nvl, SES_PROP_ELEMENT_TYPE,
 962  968              &type) == 0);
 963  969  
 964  970          switch (type) {
 965  971          case SES_ET_TEMPERATURE_SENSOR:
 966  972          case SES_ET_UPS:
 967  973          case SES_ET_VOLTAGE_SENSOR:
 968  974          case SES_ET_CURRENT_SENSOR:
 969  975                  break;
 970  976          default:
 971  977                  return (0);
 972  978          }
 973  979  
 974  980          if ((tp = ses_plugin_page_lookup(sp, snap,
 975  981              SES2_DIAGPAGE_THRESHOLD_IO, np, &len)) == NULL)
 976  982                  return (0);
 977  983  
 978  984          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_HI,
 979  985              tp->sti_high_crit);
 980  986          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_HI,
 981  987              tp->sti_high_warn);
 982  988          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_CRIT_LO,
 983  989              tp->sti_low_crit);
 984  990          SES_NV_ADD(uint64, nverr, nvl, SES_PROP_THRESH_WARN_LO,
 985  991              tp->sti_low_warn);
 986  992  
 987  993          return (0);
 988  994  }
 989  995  
 990  996  int
 991  997  ses2_fill_element_node(ses_plugin_t *sp, ses_node_t *np)
 992  998  {
 993  999          int err;
 994 1000  
 995 1001          if ((err = elem_parse_sd(sp, np)) != 0)
 996 1002                  return (err);
 997 1003  
 998 1004          if ((err = elem_parse_descr(sp, np)) != 0)
 999 1005                  return (err);
1000 1006  
1001 1007          if ((err = elem_parse_aes(sp, np)) != 0)
1002 1008                  return (err);
1003 1009  
1004 1010          if ((err = elem_parse_threshold(sp, np)) != 0)
1005 1011                  return (err);
1006 1012  
1007 1013          return (0);
1008 1014  }
  
    | 
      ↓ open down ↓ | 
    347 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX