Print this page
    
SKU fix for 5094
5094 Update libsmbios with recent items
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek<jeffpc@josefsipek.net>
Reviewed by: Garrett D'Amore <garrett@damore.org>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/common/smbios/smb_info.c
          +++ new/usr/src/common/smbios/smb_info.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   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  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 + * Copyright 2015 OmniTI Computer Consulting, Inc.  All rights reserved.
  23   24   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   25   * Use is subject to license terms.
  25   26   */
  26   27  
  27   28  /*
  28   29   * SMBIOS Information Routines
  29   30   *
  30   31   * The routines in this file are used to convert from the SMBIOS data format to
  31   32   * a more reasonable and stable set of structures offered as part of our ABI.
  32   33   * These functions take the general form:
  33   34   *
  34   35   *      stp = smb_lookup_type(shp, foo);
  35   36   *      smb_foo_t foo;
  36   37   *
  37   38   *      smb_info_bcopy(stp->smbst_hdr, &foo, sizeof (foo));
  38   39   *      bzero(caller's struct);
  39   40   *
  40   41   *      copy/convert foo members into caller's struct
  41   42   *
  42   43   * We copy the internal structure on to an automatic variable so as to avoid
  43   44   * checks everywhere for structures that the BIOS has improperly truncated, and
  44   45   * also to automatically handle the case of a structure that has been extended.
  45   46   * When necessary, this code can use smb_gteq() to determine whether the SMBIOS
  46   47   * data is of a particular revision that is supposed to contain a new field.
  47   48   */
  48   49  
  49   50  #include <sys/smbios_impl.h>
  50   51  
  51   52  #ifdef _KERNEL
  52   53  #include <sys/sunddi.h>
  53   54  #else
  54   55  #include <fcntl.h>
  55   56  #include <unistd.h>
  56   57  #include <string.h>
  57   58  #endif
  58   59  
  59   60  /*
  60   61   * A large number of SMBIOS structures contain a set of common strings used to
  61   62   * describe a h/w component's serial number, manufacturer, etc.  These fields
  62   63   * helpfully have different names and offsets and sometimes aren't consistent.
  63   64   * To simplify life for our clients, we factor these common things out into
  64   65   * smbios_info_t, which can be retrieved for any structure.  The following
  65   66   * table describes the mapping from a given structure to the smbios_info_t.
  66   67   * Multiple SMBIOS stuctures' contained objects are also handled here.
  67   68   */
  68   69  static const struct smb_infospec {
  69   70          uint8_t is_type;                /* structure type */
  70   71          uint8_t is_manu;                /* manufacturer offset */
  71   72          uint8_t is_product;             /* product name offset */
  72   73          uint8_t is_version;             /* version offset */
  73   74          uint8_t is_serial;              /* serial number offset */
  74   75          uint8_t is_asset;               /* asset tag offset */
  75   76          uint8_t is_location;            /* location string offset */
  76   77          uint8_t is_part;                /* part number offset */
  77   78          uint8_t is_contc;               /* contained count */
  78   79          uint8_t is_contsz;              /* contained size */
  79   80          uint8_t is_contv;               /* contained objects */
  80   81  } _smb_infospecs[] = {
  81   82          { SMB_TYPE_SYSTEM,
  82   83                  offsetof(smb_system_t, smbsi_manufacturer),
  83   84                  offsetof(smb_system_t, smbsi_product),
  84   85                  offsetof(smb_system_t, smbsi_version),
  85   86                  offsetof(smb_system_t, smbsi_serial),
  86   87                  0,
  87   88                  0,
  88   89                  0,
  89   90                  0,
  90   91                  0,
  91   92                  0 },
  92   93          { SMB_TYPE_BASEBOARD,
  93   94                  offsetof(smb_bboard_t, smbbb_manufacturer),
  94   95                  offsetof(smb_bboard_t, smbbb_product),
  95   96                  offsetof(smb_bboard_t, smbbb_version),
  96   97                  offsetof(smb_bboard_t, smbbb_serial),
  97   98                  offsetof(smb_bboard_t, smbbb_asset),
  98   99                  offsetof(smb_bboard_t, smbbb_location),
  99  100                  0,
 100  101                  offsetof(smb_bboard_t, smbbb_cn),
 101  102                  SMB_CONT_WORD,
 102  103                  offsetof(smb_bboard_t, smbbb_cv) },
 103  104          { SMB_TYPE_CHASSIS,
 104  105                  offsetof(smb_chassis_t, smbch_manufacturer),
 105  106                  0,
 106  107                  offsetof(smb_chassis_t, smbch_version),
 107  108                  offsetof(smb_chassis_t, smbch_serial),
 108  109                  offsetof(smb_chassis_t, smbch_asset),
 109  110                  0,
 110  111                  0,
 111  112                  offsetof(smb_chassis_t, smbch_cn),
 112  113                  SMB_CONT_BYTE,
 113  114                  offsetof(smb_chassis_t, smbch_cv) },
 114  115          { SMB_TYPE_PROCESSOR,
 115  116                  offsetof(smb_processor_t, smbpr_manufacturer),
 116  117                  0,
 117  118                  offsetof(smb_processor_t, smbpr_version),
 118  119                  offsetof(smb_processor_t, smbpr_serial),
 119  120                  offsetof(smb_processor_t, smbpr_asset),
 120  121                  offsetof(smb_processor_t, smbpr_socket),
 121  122                  offsetof(smb_processor_t, smbpr_part),
 122  123                  0,
 123  124                  0,
 124  125                  0 },
 125  126          { SMB_TYPE_CACHE,
 126  127                  0,
 127  128                  0,
 128  129                  0,
 129  130                  0,
 130  131                  0,
 131  132                  offsetof(smb_cache_t, smbca_socket),
 132  133                  0,
 133  134                  0,
 134  135                  0,
 135  136                  0 },
 136  137          { SMB_TYPE_PORT,
 137  138                  0,
 138  139                  0,
 139  140                  0,
 140  141                  0,
 141  142                  0,
 142  143                  offsetof(smb_port_t, smbpo_iref),
 143  144                  0,
 144  145                  0,
 145  146                  0,
 146  147                  0 },
 147  148          { SMB_TYPE_SLOT,
 148  149                  0,
 149  150                  0,
 150  151                  0,
 151  152                  0,
 152  153                  0,
 153  154                  offsetof(smb_slot_t, smbsl_name),
 154  155                  0,
 155  156                  0,
 156  157                  0,
 157  158                  0 },
 158  159          { SMB_TYPE_MEMDEVICE,
 159  160                  offsetof(smb_memdevice_t, smbmdev_manufacturer),
 160  161                  0,
 161  162                  0,
 162  163                  offsetof(smb_memdevice_t, smbmdev_serial),
 163  164                  offsetof(smb_memdevice_t, smbmdev_asset),
 164  165                  offsetof(smb_memdevice_t, smbmdev_dloc),
 165  166                  offsetof(smb_memdevice_t, smbmdev_part),
 166  167                  0,
 167  168                  0,
 168  169                  0 },
 169  170          { SMB_TYPE_POWERSUP,
 170  171                  offsetof(smb_powersup_t, smbpsup_manufacturer),
 171  172                  offsetof(smb_powersup_t, smbpsup_devname),
 172  173                  offsetof(smb_powersup_t, smbpsup_rev),
 173  174                  offsetof(smb_powersup_t, smbpsup_serial),
 174  175                  offsetof(smb_powersup_t, smbpsup_asset),
 175  176                  offsetof(smb_powersup_t, smbpsup_loc),
 176  177                  offsetof(smb_powersup_t, smbpsup_part),
 177  178                  0,
 178  179                  0,
 179  180                  0 },
 180  181          { SMB_TYPE_EOT }
 181  182  };
 182  183  
 183  184  static const char *
 184  185  smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n)
 185  186  {
 186  187          const uint8_t *sp = (const uint8_t *)(uintptr_t)stp->smbst_hdr;
 187  188  
 188  189          if (off != 0 && sp + off < stp->smbst_end) {
 189  190                  (*n)++; /* indicate success for caller */
 190  191                  return (smb_strptr(stp, sp[off]));
 191  192          }
 192  193  
 193  194          return (smb_strptr(stp, 0));
 194  195  }
 195  196  
 196  197  static void
 197  198  smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen)
 198  199  {
 199  200          if (dstlen > hp->smbh_len) {
 200  201                  bcopy(hp, dst, hp->smbh_len);
 201  202                  bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len);
 202  203          } else
 203  204                  bcopy(hp, dst, dstlen);
 204  205  }
 205  206  
 206  207  void
 207  208  smbios_info_smbios(smbios_hdl_t *shp, smbios_entry_t *ep)
 208  209  {
 209  210          bcopy(&shp->sh_ent, ep, sizeof (smbios_entry_t));
 210  211  }
 211  212  
 212  213  #ifndef _KERNEL
 213  214  static char smbios_product_override[256];
 214  215  static boolean_t smbios_product_checked;
 215  216  #endif
 216  217  
 217  218  int
 218  219  smbios_info_common(smbios_hdl_t *shp, id_t id, smbios_info_t *ip)
 219  220  {
 220  221          const smb_struct_t *stp = smb_lookup_id(shp, id);
 221  222          const struct smb_infospec *isp;
 222  223          int n = 0;
 223  224  
 224  225          if (stp == NULL)
 225  226                  return (-1); /* errno is set for us */
 226  227  
 227  228          for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) {
 228  229                  if (isp->is_type == stp->smbst_hdr->smbh_type)
 229  230                          break;
 230  231          }
 231  232  
 232  233          ip->smbi_manufacturer = smb_info_strptr(stp, isp->is_manu, &n);
 233  234          ip->smbi_product = smb_info_strptr(stp, isp->is_product, &n);
 234  235          ip->smbi_version = smb_info_strptr(stp, isp->is_version, &n);
 235  236          ip->smbi_serial = smb_info_strptr(stp, isp->is_serial, &n);
 236  237          ip->smbi_asset = smb_info_strptr(stp, isp->is_asset, &n);
 237  238          ip->smbi_location = smb_info_strptr(stp, isp->is_location, &n);
 238  239          ip->smbi_part = smb_info_strptr(stp, isp->is_part, &n);
 239  240  
 240  241          /*
 241  242           * This private file allows developers to experiment with reporting
 242  243           * different platform strings from SMBIOS.  It is not a supported
 243  244           * mechanism in the long term, and does not work in the kernel.
 244  245           */
 245  246  #ifndef _KERNEL
 246  247          if (isp->is_type == SMB_TYPE_SYSTEM) {
 247  248                  if (!smbios_product_checked) {
 248  249                          int fd = open("/etc/smbios_product", O_RDONLY);
 249  250                          if (fd >= 0) {
 250  251                                  (void) read(fd, smbios_product_override,
 251  252                                      sizeof (smbios_product_override) - 1);
 252  253                                  (void) close(fd);
 253  254                          }
 254  255                          smbios_product_checked = B_TRUE;
 255  256                  }
 256  257  
 257  258                  if (smbios_product_override[0] != '\0')
 258  259                          ip->smbi_product = smbios_product_override;
 259  260          }
 260  261  #endif
 261  262  
 262  263          /*
 263  264           * If we have a port with an empty internal reference designator string
 264  265           * try using the external reference designator string instead.
 265  266           */
 266  267          if (isp->is_type == SMB_TYPE_PORT && ip->smbi_location[0] == '\0') {
 267  268                  ip->smbi_location = smb_info_strptr(stp,
 268  269                      offsetof(smb_port_t, smbpo_eref), &n);
 269  270          }
 270  271  
 271  272          return (n ? 0 : smb_set_errno(shp, ESMB_NOINFO));
 272  273  }
 273  274  
 274  275  /*
 275  276   * Returns the actual number of contained objects.
 276  277   *
 277  278   * idc - number of contained objects
 278  279   * idv - returned array of contained objects
 279  280   */
 280  281  int
 281  282  smbios_info_contains(smbios_hdl_t *shp, id_t id, uint_t idc, id_t *idv)
 282  283  {
 283  284          const smb_struct_t *stp = smb_lookup_id(shp, id);
 284  285          const struct smb_infospec *isp;
 285  286          id_t *cp;
 286  287          uint_t size;
 287  288          uint8_t cnt;
 288  289          int i, n;
 289  290  
 290  291          if (stp == NULL) {
 291  292                  return (-1); /* errno is set for us */
 292  293          }
 293  294  
 294  295          for (isp = _smb_infospecs; isp->is_type != SMB_TYPE_EOT; isp++) {
 295  296                  if (isp->is_type == stp->smbst_hdr->smbh_type)
 296  297                          break;
 297  298          }
 298  299          if (isp->is_type == SMB_TYPE_EOT)
 299  300                  return (smb_set_errno(shp, ESMB_TYPE));
 300  301  
 301  302          size = isp->is_contsz;
 302  303          cnt = *((uint8_t *)(uintptr_t)stp->smbst_hdr + isp->is_contc);
 303  304          cp = (id_t *)((uintptr_t)stp->smbst_hdr + isp->is_contv);
 304  305  
 305  306          n = MIN(cnt, idc);
 306  307          for (i = 0; i < n; i++) {
 307  308                  if (size == SMB_CONT_WORD)
 308  309                          idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 2));
 309  310                  else if (size == SMB_CONT_BYTE)
 310  311                          idv[i] = *((uint8_t *)(uintptr_t)cp + (i * 3));
 311  312                  else
 312  313                          return (smb_set_errno(shp, ESMB_INVAL));
 313  314          }
 314  315  
 315  316          return (cnt);
 316  317  }
 317  318  
 318  319  id_t
 319  320  smbios_info_bios(smbios_hdl_t *shp, smbios_bios_t *bp)
 320  321  {
 321  322          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BIOS);
 322  323          const smb_bios_t *bip;
 323  324  
 324  325          if (stp == NULL)
 325  326                  return (-1); /* errno is set for us */
 326  327  
 327  328          if (stp->smbst_hdr->smbh_len < sizeof (smb_bios_t) - sizeof (uint8_t))
 328  329                  return (smb_set_errno(shp, ESMB_CORRUPT));
 329  330  
 330  331          bip = (smb_bios_t *)(uintptr_t)stp->smbst_hdr;
 331  332          bzero(bp, sizeof (smbios_bios_t));
 332  333  
 333  334          bp->smbb_vendor = smb_strptr(stp, bip->smbbi_vendor);
 334  335          bp->smbb_version = smb_strptr(stp, bip->smbbi_version);
 335  336          bp->smbb_segment = bip->smbbi_segment;
 336  337          bp->smbb_reldate = smb_strptr(stp, bip->smbbi_reldate);
 337  338          bp->smbb_romsize = 64 * 1024 * ((uint32_t)bip->smbbi_romsize + 1);
 338  339          bp->smbb_runsize = 16 * (0x10000 - (uint32_t)bip->smbbi_segment);
 339  340          bp->smbb_cflags = bip->smbbi_cflags;
 340  341  
 341  342          /*
 342  343           * If one or more extension bytes are present, reset smbb_xcflags to
 343  344           * point to them.  Otherwise leave this member set to NULL.
 344  345           */
 345  346          if (stp->smbst_hdr->smbh_len >= sizeof (smb_bios_t)) {
 346  347                  bp->smbb_xcflags = bip->smbbi_xcflags;
 347  348                  bp->smbb_nxcflags = stp->smbst_hdr->smbh_len -
 348  349                      sizeof (smb_bios_t) + 1;
 349  350  
 350  351                  if (bp->smbb_nxcflags > SMB_BIOSXB_ECFW_MIN &&
 351  352                      smb_gteq(shp, SMB_VERSION_24)) {
 352  353                          bp->smbb_biosv.smbv_major =
 353  354                              bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MAJ];
 354  355                          bp->smbb_biosv.smbv_minor =
 355  356                              bip->smbbi_xcflags[SMB_BIOSXB_BIOS_MIN];
 356  357                          bp->smbb_ecfwv.smbv_major =
 357  358                              bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MAJ];
 358  359                          bp->smbb_ecfwv.smbv_minor =
 359  360                              bip->smbbi_xcflags[SMB_BIOSXB_ECFW_MIN];
 360  361                  }
 361  362          }
 362  363  
 363  364          return (stp->smbst_hdr->smbh_hdl);
 364  365  }
 365  366  
 366  367  id_t
 367  368  smbios_info_system(smbios_hdl_t *shp, smbios_system_t *sip)
 368  369  {
 369  370          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM);
 370  371          smb_system_t si;
 371  372  
 372  373          if (stp == NULL)
 373  374                  return (-1); /* errno is set for us */
 374  375  
 375  376          smb_info_bcopy(stp->smbst_hdr, &si, sizeof (si));
 376  377          bzero(sip, sizeof (smbios_system_t));
 377  378  
 378  379          sip->smbs_uuid = ((smb_system_t *)stp->smbst_hdr)->smbsi_uuid;
 379  380          sip->smbs_uuidlen = sizeof (si.smbsi_uuid);
 380  381          sip->smbs_wakeup = si.smbsi_wakeup;
 381  382          sip->smbs_sku = smb_strptr(stp, si.smbsi_sku);
 382  383          sip->smbs_family = smb_strptr(stp, si.smbsi_family);
 383  384  
 384  385          return (stp->smbst_hdr->smbh_hdl);
 385  386  }
 386  387  
 387  388  int
 388  389  smbios_info_bboard(smbios_hdl_t *shp, id_t id, smbios_bboard_t *bbp)
 389  390  {
 390  391          const smb_struct_t *stp = smb_lookup_id(shp, id);
 391  392          smb_bboard_t bb;
 392  393  
 393  394          if (stp == NULL)
 394  395                  return (-1); /* errno is set for us */
 395  396  
 396  397          if (stp->smbst_hdr->smbh_type != SMB_TYPE_BASEBOARD)
 397  398                  return (smb_set_errno(shp, ESMB_TYPE));
 398  399  
 399  400          smb_info_bcopy(stp->smbst_hdr, &bb, sizeof (bb));
 400  401          bzero(bbp, sizeof (smbios_bboard_t));
 401  402  
 402  403          bbp->smbb_chassis = bb.smbbb_chassis;
 403  404          bbp->smbb_flags = bb.smbbb_flags;
  
    | 
      ↓ open down ↓ | 
    371 lines elided | 
    
      ↑ open up ↑ | 
  
 404  405          bbp->smbb_type = bb.smbbb_type;
 405  406          bbp->smbb_contn = bb.smbbb_cn;
 406  407  
 407  408          return (0);
 408  409  }
 409  410  
 410  411  int
 411  412  smbios_info_chassis(smbios_hdl_t *shp, id_t id, smbios_chassis_t *chp)
 412  413  {
 413  414          const smb_struct_t *stp = smb_lookup_id(shp, id);
 414      -        smb_chassis_t ch;
      415 +        /* Length is measurable by one byte, so it'll be no more than 255. */
      416 +        uint8_t buf[256]
      417 +        smb_chassis_t *ch = (smb_chassis_t *)&(buf[0]);
 415  418  
 416  419          if (stp == NULL)
 417  420                  return (-1); /* errno is set for us */
 418  421  
 419  422          if (stp->smbst_hdr->smbh_type != SMB_TYPE_CHASSIS)
 420  423                  return (smb_set_errno(shp, ESMB_TYPE));
 421  424  
 422      -        smb_info_bcopy(stp->smbst_hdr, &ch, sizeof (ch));
      425 +        smb_info_bcopy(stp->smbst_hdr, ch, sizeof (buf));
 423  426          bzero(chp, sizeof (smbios_chassis_t));
 424  427  
 425      -        chp->smbc_oemdata = ch.smbch_oemdata;
 426      -        chp->smbc_lock = (ch.smbch_type & SMB_CHT_LOCK) != 0;
 427      -        chp->smbc_type = ch.smbch_type & ~SMB_CHT_LOCK;
 428      -        chp->smbc_bustate = ch.smbch_bustate;
 429      -        chp->smbc_psstate = ch.smbch_psstate;
 430      -        chp->smbc_thstate = ch.smbch_thstate;
 431      -        chp->smbc_security = ch.smbch_security;
 432      -        chp->smbc_uheight = ch.smbch_uheight;
 433      -        chp->smbc_cords = ch.smbch_cords;
 434      -        chp->smbc_elems = ch.smbch_cn;
 435      -        chp->smbc_elemlen = ch.smbch_cm;
      428 +        chp->smbc_oemdata = ch->smbch_oemdata;
      429 +        chp->smbc_lock = (ch->smbch_type & SMB_CHT_LOCK) != 0;
      430 +        chp->smbc_type = ch->smbch_type & ~SMB_CHT_LOCK;
      431 +        chp->smbc_bustate = ch->smbch_bustate;
      432 +        chp->smbc_psstate = ch->smbch_psstate;
      433 +        chp->smbc_thstate = ch->smbch_thstate;
      434 +        chp->smbc_security = ch->smbch_security;
      435 +        chp->smbc_uheight = ch->smbch_uheight;
      436 +        chp->smbc_cords = ch->smbch_cords;
      437 +        chp->smbc_elems = ch->smbch_cn;
      438 +        chp->smbc_elemlen = ch->smbch_cm;
 436  439  
      440 +        if (shp->sh_smbvers >= SMB_VERSION_27) {
      441 +                (void) strlcpy(chp->smbc_sku, SMB_CH_SKU(ch),
      442 +                    sizeof (chp->smbc_sku));
      443 +        }
      444 +
 437  445          return (0);
 438  446  }
 439  447  
 440  448  int
 441  449  smbios_info_processor(smbios_hdl_t *shp, id_t id, smbios_processor_t *pp)
 442  450  {
 443  451          const smb_struct_t *stp = smb_lookup_id(shp, id);
 444  452          smb_processor_t p;
 445  453  
 446  454          if (stp == NULL)
 447  455                  return (-1); /* errno is set for us */
 448  456  
 449  457          if (stp->smbst_hdr->smbh_type != SMB_TYPE_PROCESSOR)
 450  458                  return (smb_set_errno(shp, ESMB_TYPE));
 451  459  
 452  460          smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
 453  461          bzero(pp, sizeof (smbios_processor_t));
 454  462  
 455  463          pp->smbp_cpuid = p.smbpr_cpuid;
 456  464          pp->smbp_type = p.smbpr_type;
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 457  465          pp->smbp_family = p.smbpr_family;
 458  466          pp->smbp_voltage = p.smbpr_voltage;
 459  467          pp->smbp_maxspeed = p.smbpr_maxspeed;
 460  468          pp->smbp_curspeed = p.smbpr_curspeed;
 461  469          pp->smbp_status = p.smbpr_status;
 462  470          pp->smbp_upgrade = p.smbpr_upgrade;
 463  471          pp->smbp_l1cache = p.smbpr_l1cache;
 464  472          pp->smbp_l2cache = p.smbpr_l2cache;
 465  473          pp->smbp_l3cache = p.smbpr_l3cache;
 466  474  
      475 +        if (shp->sh_smbvers >= SMB_VERSION_25) {
      476 +                pp->smbp_corecount = p.smbpr_corecount;
      477 +                pp->smbp_coresenabled = p.smbpr_coresenabled;
      478 +                pp->smbp_threadcount = p.smbpr_threadcount;
      479 +                pp->smbp_cflags = p.smbpr_cflags;
      480 +        }
      481 +
      482 +        if (shp->sh_smbvers >= SMB_VERSION_26)
      483 +                pp->smbp_family2 = p.smbpr_family2;
      484 +
 467  485          return (0);
 468  486  }
 469  487  
 470  488  int
 471  489  smbios_info_cache(smbios_hdl_t *shp, id_t id, smbios_cache_t *cap)
 472  490  {
 473  491          const smb_struct_t *stp = smb_lookup_id(shp, id);
 474  492          smb_cache_t c;
 475  493  
 476  494          if (stp == NULL)
 477  495                  return (-1); /* errno is set for us */
 478  496  
 479  497          if (stp->smbst_hdr->smbh_type != SMB_TYPE_CACHE)
 480  498                  return (smb_set_errno(shp, ESMB_TYPE));
 481  499  
 482  500          smb_info_bcopy(stp->smbst_hdr, &c, sizeof (c));
 483  501          bzero(cap, sizeof (smbios_cache_t));
 484  502  
 485  503          cap->smba_maxsize = SMB_CACHE_SIZE(c.smbca_maxsize);
 486  504          cap->smba_size = SMB_CACHE_SIZE(c.smbca_size);
 487  505          cap->smba_stype = c.smbca_stype;
 488  506          cap->smba_ctype = c.smbca_ctype;
 489  507          cap->smba_speed = c.smbca_speed;
 490  508          cap->smba_etype = c.smbca_etype;
 491  509          cap->smba_ltype = c.smbca_ltype;
 492  510          cap->smba_assoc = c.smbca_assoc;
 493  511          cap->smba_level = SMB_CACHE_CFG_LEVEL(c.smbca_config);
 494  512          cap->smba_mode = SMB_CACHE_CFG_MODE(c.smbca_config);
 495  513          cap->smba_location = SMB_CACHE_CFG_LOCATION(c.smbca_config);
 496  514  
 497  515          if (SMB_CACHE_CFG_ENABLED(c.smbca_config))
 498  516                  cap->smba_flags |= SMB_CAF_ENABLED;
 499  517  
 500  518          if (SMB_CACHE_CFG_SOCKETED(c.smbca_config))
 501  519                  cap->smba_flags |= SMB_CAF_SOCKETED;
 502  520  
 503  521          return (0);
 504  522  }
 505  523  
 506  524  int
 507  525  smbios_info_port(smbios_hdl_t *shp, id_t id, smbios_port_t *pop)
 508  526  {
 509  527          const smb_struct_t *stp = smb_lookup_id(shp, id);
 510  528          smb_port_t p;
 511  529  
 512  530          if (stp == NULL)
 513  531                  return (-1); /* errno is set for us */
 514  532  
 515  533          if (stp->smbst_hdr->smbh_type != SMB_TYPE_PORT)
 516  534                  return (smb_set_errno(shp, ESMB_TYPE));
 517  535  
 518  536          smb_info_bcopy(stp->smbst_hdr, &p, sizeof (p));
 519  537          bzero(pop, sizeof (smbios_port_t));
 520  538  
 521  539          pop->smbo_iref = smb_strptr(stp, p.smbpo_iref);
 522  540          pop->smbo_eref = smb_strptr(stp, p.smbpo_eref);
 523  541  
 524  542          pop->smbo_itype = p.smbpo_itype;
 525  543          pop->smbo_etype = p.smbpo_etype;
 526  544          pop->smbo_ptype = p.smbpo_ptype;
 527  545  
 528  546          return (0);
 529  547  }
 530  548  
 531  549  int
 532  550  smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp)
 533  551  {
 534  552          const smb_struct_t *stp = smb_lookup_id(shp, id);
 535  553          smb_slot_t s;
 536  554  
 537  555          if (stp == NULL)
 538  556                  return (-1); /* errno is set for us */
 539  557  
 540  558          if (stp->smbst_hdr->smbh_type != SMB_TYPE_SLOT)
 541  559                  return (smb_set_errno(shp, ESMB_TYPE));
 542  560  
 543  561          smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
 544  562          bzero(sp, sizeof (smbios_slot_t));
 545  563  
 546  564          sp->smbl_name = smb_strptr(stp, s.smbsl_name);
 547  565          sp->smbl_type = s.smbsl_type;
 548  566          sp->smbl_width = s.smbsl_width;
 549  567          sp->smbl_usage = s.smbsl_usage;
 550  568          sp->smbl_length = s.smbsl_length;
 551  569          sp->smbl_id = s.smbsl_id;
 552  570          sp->smbl_ch1 = s.smbsl_ch1;
 553  571          sp->smbl_ch2 = s.smbsl_ch2;
 554  572          sp->smbl_sg = s.smbsl_sg;
 555  573          sp->smbl_bus = s.smbsl_bus;
 556  574          sp->smbl_df = s.smbsl_df;
 557  575  
 558  576          return (0);
 559  577  }
 560  578  
 561  579  int
 562  580  smbios_info_obdevs_ext(smbios_hdl_t *shp, id_t id, smbios_obdev_ext_t *oep)
 563  581  {
 564  582          const smb_struct_t *stp = smb_lookup_id(shp, id);
 565  583          smb_obdev_ext_t obe;
 566  584  
 567  585          if (stp == NULL)
 568  586                  return (-1); /* errno is set for us */
 569  587  
 570  588          if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVEXT)
 571  589                  return (smb_set_errno(shp, ESMB_TYPE));
 572  590  
 573  591          smb_info_bcopy(stp->smbst_hdr, &obe, sizeof (obe));
 574  592          bzero(oep, sizeof (smbios_obdev_ext_t));
 575  593  
 576  594          oep->smboe_name = smb_strptr(stp, obe.smbobe_name);
 577  595          oep->smboe_dtype = obe.smbobe_dtype;
 578  596          oep->smboe_dti = obe.smbobe_dti;
 579  597          oep->smboe_sg = obe.smbobe_sg;
 580  598          oep->smboe_bus = obe.smbobe_bus;
 581  599          oep->smboe_df = obe.smbobe_df;
 582  600  
 583  601          return (0);
 584  602  }
 585  603  
 586  604  int
 587  605  smbios_info_obdevs(smbios_hdl_t *shp, id_t id, int obc, smbios_obdev_t *obp)
 588  606  {
 589  607          const smb_struct_t *stp = smb_lookup_id(shp, id);
 590  608          const smb_obdev_t *op;
 591  609          int i, m, n;
 592  610  
 593  611          if (stp == NULL)
 594  612                  return (-1); /* errno is set for us */
 595  613  
 596  614          if (stp->smbst_hdr->smbh_type != SMB_TYPE_OBDEVS)
 597  615                  return (smb_set_errno(shp, ESMB_TYPE));
 598  616  
 599  617          op = (smb_obdev_t *)((uintptr_t)stp->smbst_hdr + sizeof (smb_header_t));
 600  618          m = (stp->smbst_hdr->smbh_len - sizeof (smb_header_t)) / sizeof (*op);
 601  619          n = MIN(m, obc);
 602  620  
 603  621          for (i = 0; i < n; i++, op++, obp++) {
 604  622                  obp->smbd_name = smb_strptr(stp, op->smbob_name);
 605  623                  obp->smbd_type = op->smbob_type & ~SMB_OBT_ENABLED;
 606  624                  obp->smbd_enabled = (op->smbob_type & SMB_OBT_ENABLED) != 0;
 607  625          }
 608  626  
 609  627          return (m);
 610  628  }
 611  629  
 612  630  /*
 613  631   * The implementation structures for OEMSTR, SYSCONFSTR, and LANG all use the
 614  632   * first byte to indicate the size of a string table at the end of the record.
 615  633   * Therefore, smbios_info_strtab() can be used to retrieve the table size and
 616  634   * strings for any of these underlying record types.
 617  635   */
 618  636  int
 619  637  smbios_info_strtab(smbios_hdl_t *shp, id_t id, int argc, const char *argv[])
 620  638  {
 621  639          const smb_struct_t *stp = smb_lookup_id(shp, id);
 622  640          smb_strtab_t s;
 623  641          int i, n;
 624  642  
 625  643          if (stp == NULL)
 626  644                  return (-1); /* errno is set for us */
 627  645  
 628  646          if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR &&
 629  647              stp->smbst_hdr->smbh_type != SMB_TYPE_SYSCONFSTR &&
 630  648              stp->smbst_hdr->smbh_type != SMB_TYPE_LANG)
 631  649                  return (smb_set_errno(shp, ESMB_TYPE));
 632  650  
 633  651          smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
 634  652          n = MIN(s.smbtb_count, argc);
 635  653  
 636  654          for (i = 0; i < n; i++)
 637  655                  argv[i] = smb_strptr(stp, i + 1);
 638  656  
 639  657          return (s.smbtb_count);
 640  658  }
 641  659  
 642  660  id_t
 643  661  smbios_info_lang(smbios_hdl_t *shp, smbios_lang_t *lp)
 644  662  {
 645  663          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_LANG);
 646  664          smb_lang_t l;
 647  665  
 648  666          if (stp == NULL)
 649  667                  return (-1); /* errno is set for us */
 650  668  
 651  669          smb_info_bcopy(stp->smbst_hdr, &l, sizeof (l));
 652  670          bzero(lp, sizeof (smbios_lang_t));
 653  671  
 654  672          lp->smbla_cur = smb_strptr(stp, l.smblang_cur);
 655  673          lp->smbla_fmt = l.smblang_flags & 1;
 656  674          lp->smbla_num = l.smblang_num;
 657  675  
 658  676          return (stp->smbst_hdr->smbh_hdl);
 659  677  }
 660  678  
 661  679  id_t
 662  680  smbios_info_eventlog(smbios_hdl_t *shp, smbios_evlog_t *evp)
 663  681  {
 664  682          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_EVENTLOG);
 665  683          const smb_sel_t *sel;
 666  684          size_t len;
 667  685  
 668  686          if (stp == NULL)
 669  687                  return (-1); /* errno is set for us */
 670  688  
 671  689          if (stp->smbst_hdr->smbh_len < sizeof (smb_sel_t) - sizeof (uint8_t))
 672  690                  return (smb_set_errno(shp, ESMB_CORRUPT));
 673  691  
 674  692          sel = (smb_sel_t *)(uintptr_t)stp->smbst_hdr;
 675  693          len = stp->smbst_hdr->smbh_len - sizeof (smb_sel_t) + sizeof (uint8_t);
 676  694          bzero(evp, sizeof (smbios_evlog_t));
 677  695  
 678  696          if (len < sel->smbsel_typec * sel->smbsel_typesz)
 679  697                  return (smb_set_errno(shp, ESMB_CORRUPT));
 680  698  
 681  699          evp->smbev_size = sel->smbsel_len;
 682  700          evp->smbev_hdr = sel->smbsel_hdroff;
 683  701          evp->smbev_data = sel->smbsel_dataoff;
 684  702          evp->smbev_method = sel->smbsel_method;
 685  703          evp->smbev_flags = sel->smbsel_status;
 686  704          evp->smbev_format = sel->smbsel_format;
 687  705          evp->smbev_token = sel->smbsel_token;
 688  706          evp->smbev_addr.eva_addr = sel->smbsel_addr;
 689  707  
 690  708          if (sel->smbsel_typesz == sizeof (smbios_evtype_t)) {
 691  709                  evp->smbev_typec = sel->smbsel_typec;
 692  710                  evp->smbev_typev = (void *)(uintptr_t)sel->smbsel_typev;
 693  711          }
 694  712  
 695  713          return (stp->smbst_hdr->smbh_hdl);
 696  714  }
 697  715  
 698  716  int
 699  717  smbios_info_memarray(smbios_hdl_t *shp, id_t id, smbios_memarray_t *map)
 700  718  {
 701  719          const smb_struct_t *stp = smb_lookup_id(shp, id);
 702  720          smb_memarray_t m;
 703  721  
 704  722          if (stp == NULL)
 705  723                  return (-1); /* errno is set for us */
 706  724  
 707  725          if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAY)
 708  726                  return (smb_set_errno(shp, ESMB_TYPE));
 709  727  
 710  728          smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
  
    | 
      ↓ open down ↓ | 
    234 lines elided | 
    
      ↑ open up ↑ | 
  
 711  729          bzero(map, sizeof (smbios_memarray_t));
 712  730  
 713  731          map->smbma_location = m.smbmarr_loc;
 714  732          map->smbma_use = m.smbmarr_use;
 715  733          map->smbma_ecc = m.smbmarr_ecc;
 716  734          map->smbma_ndevs = m.smbmarr_ndevs;
 717  735          map->smbma_err = m.smbmarr_err;
 718  736  
 719  737          if (m.smbmarr_cap != 0x80000000)
 720  738                  map->smbma_size = (uint64_t)m.smbmarr_cap * 1024;
      739 +        else if (m.smbmarr_extcap != 0)
      740 +                map->smbma_size = m.smbmarr_extcap;
 721  741          else
 722  742                  map->smbma_size = 0; /* unknown */
 723  743  
 724  744          return (0);
 725  745  }
 726  746  
 727  747  int
 728  748  smbios_info_memarrmap(smbios_hdl_t *shp, id_t id, smbios_memarrmap_t *map)
 729  749  {
 730  750          const smb_struct_t *stp = smb_lookup_id(shp, id);
 731  751          smb_memarrmap_t m;
 732  752  
 733  753          if (stp == NULL)
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 734  754                  return (-1); /* errno is set for us */
 735  755  
 736  756          if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMARRAYMAP)
 737  757                  return (smb_set_errno(shp, ESMB_TYPE));
 738  758  
 739  759          smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
 740  760          bzero(map, sizeof (smbios_memarrmap_t));
 741  761  
 742  762          map->smbmam_array = m.smbamap_array;
 743  763          map->smbmam_width = m.smbamap_width;
 744      -        map->smbmam_addr = (uint64_t)m.smbamap_start * 1024;
 745      -        map->smbmam_size = (uint64_t)
 746      -            (m.smbamap_end - m.smbamap_start + 1) * 1024;
 747  764  
      765 +        if (m.smbamap_start != 0xFFFFFFFF && m.smbamap_end != 0xFFFFFFFF) {
      766 +                map->smbmam_addr = (uint64_t)m.smbamap_start * 1024;
      767 +                map->smbmam_size = (uint64_t)
      768 +                    (m.smbamap_end - m.smbamap_start + 1) * 1024;
      769 +        } else if (m.smbamap_extstart != 0 && m.smbamap_extend != 0) {
      770 +                map->smbmam_addr = m.smbamap_extstart;
      771 +                map->smbmam_size = m.smbamap_extend - m.smbamap_extstart + 1;
      772 +        }
      773 +
 748  774          return (0);
 749  775  }
 750  776  
 751  777  int
 752  778  smbios_info_memdevice(smbios_hdl_t *shp, id_t id, smbios_memdevice_t *mdp)
 753  779  {
 754  780          const smb_struct_t *stp = smb_lookup_id(shp, id);
 755  781          smb_memdevice_t m;
 756  782  
 757  783          if (stp == NULL)
 758  784                  return (-1); /* errno is set for us */
 759  785  
 760  786          if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICE)
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 761  787                  return (smb_set_errno(shp, ESMB_TYPE));
 762  788  
 763  789          smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
 764  790          bzero(mdp, sizeof (smbios_memdevice_t));
 765  791  
 766  792          mdp->smbmd_array = m.smbmdev_array;
 767  793          mdp->smbmd_error = m.smbmdev_error;
 768  794          mdp->smbmd_twidth = m.smbmdev_twidth == 0xFFFF ? -1U : m.smbmdev_twidth;
 769  795          mdp->smbmd_dwidth = m.smbmdev_dwidth == 0xFFFF ? -1U : m.smbmdev_dwidth;
 770  796  
 771      -        if (mdp->smbmd_size != 0xFFFF) {
      797 +        if (m.smbmdev_size == 0x7FFF) {
      798 +                mdp->smbmd_size = (uint64_t)m.smbmdev_extsize;
      799 +                mdp->smbmd_size *= 1024 * 1024; /* convert MB to bytes */
      800 +        } else if (m.smbmdev_size != 0xFFFF) {
 772  801                  mdp->smbmd_size = (uint64_t)(m.smbmdev_size & ~SMB_MDS_KBYTES);
 773  802                  if (m.smbmdev_size & SMB_MDS_KBYTES)
 774  803                          mdp->smbmd_size *= 1024;
 775  804                  else
 776  805                          mdp->smbmd_size *= 1024 * 1024;
 777  806          } else
 778  807                  mdp->smbmd_size = -1ULL; /* size unknown */
 779  808  
 780  809          mdp->smbmd_form = m.smbmdev_form;
 781  810          mdp->smbmd_set = m.smbmdev_set;
 782  811          mdp->smbmd_type = m.smbmdev_type;
      812 +        mdp->smbmd_speed = m.smbmdev_speed;
 783  813          mdp->smbmd_flags = m.smbmdev_flags;
 784  814          mdp->smbmd_dloc = smb_strptr(stp, m.smbmdev_dloc);
 785  815          mdp->smbmd_bloc = smb_strptr(stp, m.smbmdev_bloc);
 786  816  
 787      -        if (m.smbmdev_speed != 0)
 788      -                mdp->smbmd_speed = 1000 / m.smbmdev_speed; /* MHz -> nsec */
      817 +        if (shp->sh_smbvers >= SMB_VERSION_26)
      818 +                mdp->smbmd_rank = m.smbmdev_attrs & 0x0F;
 789  819  
      820 +        if (shp->sh_smbvers >= SMB_VERSION_27)
      821 +                mdp->smbmd_clkspeed = m.smbmdev_clkspeed;
      822 +
      823 +        if (shp->sh_smbvers >= SMB_VERSION_28) {
      824 +                mdp->smbmd_minvolt = m.smbmdev_minvolt;
      825 +                mdp->smbmd_maxvolt = m.smbmdev_maxvolt;
      826 +                mdp->smbmd_confvolt = m.smbmdev_confvolt;
      827 +        }
      828 +
 790  829          return (0);
 791  830  }
 792  831  
 793  832  int
 794  833  smbios_info_memdevmap(smbios_hdl_t *shp, id_t id, smbios_memdevmap_t *mdp)
 795  834  {
 796  835          const smb_struct_t *stp = smb_lookup_id(shp, id);
 797  836          smb_memdevmap_t m;
 798  837  
 799  838          if (stp == NULL)
 800  839                  return (-1); /* errno is set for us */
 801  840  
 802  841          if (stp->smbst_hdr->smbh_type != SMB_TYPE_MEMDEVICEMAP)
 803  842                  return (smb_set_errno(shp, ESMB_TYPE));
 804  843  
 805  844          smb_info_bcopy(stp->smbst_hdr, &m, sizeof (m));
 806  845          bzero(mdp, sizeof (smbios_memdevmap_t));
 807  846  
 808  847          mdp->smbmdm_device = m.smbdmap_device;
 809  848          mdp->smbmdm_arrmap = m.smbdmap_array;
 810      -        mdp->smbmdm_addr = (uint64_t)m.smbdmap_start * 1024;
 811      -        mdp->smbmdm_size = (uint64_t)
 812      -            (m.smbdmap_end - m.smbdmap_start + 1) * 1024;
 813  849          mdp->smbmdm_rpos = m.smbdmap_rpos;
 814  850          mdp->smbmdm_ipos = m.smbdmap_ipos;
 815  851          mdp->smbmdm_idepth = m.smbdmap_idepth;
 816  852  
      853 +        if (m.smbdmap_start != 0xFFFFFFFF && m.smbdmap_end != 0xFFFFFFFF) {
      854 +                mdp->smbmdm_addr = (uint64_t)m.smbdmap_start * 1024;
      855 +                mdp->smbmdm_size = (uint64_t)
      856 +                    (m.smbdmap_end - m.smbdmap_start + 1) * 1024;
      857 +        } else if (m.smbdmap_extstart != 0 && m.smbdmap_extend != 0) {
      858 +                mdp->smbmdm_addr = m.smbdmap_extstart;
      859 +                mdp->smbmdm_size = m.smbdmap_extend - m.smbdmap_extstart + 1;
      860 +        }
      861 +
 817  862          return (0);
 818  863  }
 819  864  
 820  865  id_t
 821  866  smbios_info_hwsec(smbios_hdl_t *shp, smbios_hwsec_t *hsp)
 822  867  {
 823  868          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_SECURITY);
 824  869          smb_hwsec_t hs;
 825  870  
 826  871          if (stp == NULL)
 827  872                  return (-1); /* errno is set for us */
 828  873  
 829  874          smb_info_bcopy(stp->smbst_hdr, &hs, sizeof (hs));
 830  875          bzero(hsp, sizeof (smbios_hwsec_t));
 831  876  
 832  877          hsp->smbh_pwr_ps = SMB_HWS_PWR_PS(hs.smbhs_settings);
 833  878          hsp->smbh_kbd_ps = SMB_HWS_KBD_PS(hs.smbhs_settings);
 834  879          hsp->smbh_adm_ps = SMB_HWS_ADM_PS(hs.smbhs_settings);
 835  880          hsp->smbh_pan_ps = SMB_HWS_PAN_PS(hs.smbhs_settings);
 836  881  
 837  882          return (stp->smbst_hdr->smbh_hdl);
 838  883  }
 839  884  
 840  885  id_t
 841  886  smbios_info_boot(smbios_hdl_t *shp, smbios_boot_t *bp)
 842  887  {
 843  888          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_BOOT);
 844  889          const smb_boot_t *b = (smb_boot_t *)(uintptr_t)stp->smbst_hdr;
 845  890  
 846  891          if (stp == NULL)
 847  892                  return (-1); /* errno is set for us */
 848  893  
 849  894          bzero(bp, sizeof (smbios_boot_t));
 850  895  
 851  896          bp->smbt_status = b->smbbo_status[0];
 852  897          bp->smbt_size = stp->smbst_hdr->smbh_len - sizeof (smb_boot_t);
 853  898          bp->smbt_data = bp->smbt_size ? &b->smbbo_status[1] : NULL;
 854  899  
 855  900          return (stp->smbst_hdr->smbh_hdl);
 856  901  }
 857  902  
 858  903  id_t
 859  904  smbios_info_ipmi(smbios_hdl_t *shp, smbios_ipmi_t *ip)
 860  905  {
 861  906          const smb_struct_t *stp = smb_lookup_type(shp, SMB_TYPE_IPMIDEV);
 862  907          smb_ipmi_t i;
 863  908  
 864  909          if (stp == NULL)
 865  910                  return (-1); /* errno is set for us */
 866  911  
 867  912          smb_info_bcopy(stp->smbst_hdr, &i, sizeof (i));
 868  913          bzero(ip, sizeof (smbios_ipmi_t));
 869  914  
 870  915          ip->smbip_type = i.smbipm_type;
 871  916          ip->smbip_vers.smbv_major = SMB_IPM_SPEC_MAJOR(i.smbipm_spec);
 872  917          ip->smbip_vers.smbv_minor = SMB_IPM_SPEC_MINOR(i.smbipm_spec);
 873  918          ip->smbip_i2c = i.smbipm_i2c;
 874  919          ip->smbip_addr = i.smbipm_addr & ~SMB_IPM_ADDR_IO;
 875  920          ip->smbip_intr = i.smbipm_intr;
 876  921  
 877  922          if (i.smbipm_bus != (uint8_t)-1)
 878  923                  ip->smbip_bus = i.smbipm_bus;
 879  924          else
 880  925                  ip->smbip_bus = -1u;
 881  926  
 882  927          if (SMB_IPM_INFO_LSB(i.smbipm_info))
 883  928                  ip->smbip_addr |= 1; /* turn on least-significant bit of addr */
 884  929  
 885  930          if (i.smbipm_addr & SMB_IPM_ADDR_IO) {
 886  931                  switch (SMB_IPM_INFO_REGS(i.smbipm_info)) {
 887  932                  case SMB_IPM_REGS_1B:
 888  933                          ip->smbip_regspacing = 1;
 889  934                          break;
 890  935                  case SMB_IPM_REGS_4B:
 891  936                          ip->smbip_regspacing = 4;
 892  937                          break;
 893  938                  case SMB_IPM_REGS_16B:
 894  939                          ip->smbip_regspacing = 16;
 895  940                          break;
 896  941                  default:
 897  942                          ip->smbip_regspacing = 1;
 898  943                  }
 899  944                  ip->smbip_flags |= SMB_IPMI_F_IOADDR;
 900  945          }
 901  946  
 902  947          if (SMB_IPM_INFO_ISPEC(i.smbipm_info))
 903  948                  ip->smbip_flags |= SMB_IPMI_F_INTRSPEC;
 904  949  
 905  950          if (SMB_IPM_INFO_IPOL(i.smbipm_info) == SMB_IPM_IPOL_HI)
 906  951                  ip->smbip_flags |= SMB_IPMI_F_INTRHIGH;
 907  952  
 908  953          if (SMB_IPM_INFO_IMODE(i.smbipm_info) == SMB_IPM_IMODE_EDGE)
 909  954                  ip->smbip_flags |= SMB_IPMI_F_INTREDGE;
 910  955  
 911  956          return (stp->smbst_hdr->smbh_hdl);
 912  957  }
 913  958  
 914  959  static boolean_t
 915  960  smbios_has_oemstr(smbios_hdl_t *shp, const char *oemstr)
 916  961  {
 917  962          const smb_struct_t *stp = shp->sh_structs;
 918  963          smb_strtab_t s;
 919  964          int i, j;
 920  965  
 921  966          for (i = 0; i < shp->sh_nstructs; i++, stp++) {
 922  967                  if (stp->smbst_hdr->smbh_type != SMB_TYPE_OEMSTR)
 923  968                          continue;
 924  969  
 925  970                  smb_info_bcopy(stp->smbst_hdr, &s, sizeof (s));
 926  971                  for (j = 0; j < s.smbtb_count; j++)
 927  972                          if (strcmp(smb_strptr(stp, j + 1), oemstr) == 0)
 928  973                                  return (B_TRUE);
 929  974          }
 930  975  
 931  976          return (B_FALSE);
 932  977  }
 933  978  
 934  979  static const char *
 935  980  smb_serial_valid(const char *serial)
 936  981  {
 937  982          char buf[MAXNAMELEN];
 938  983          int i = 0;
 939  984  
 940  985          if (serial == NULL)
 941  986                  return (NULL);
 942  987  
 943  988          (void) strlcpy(buf, serial, sizeof (buf));
 944  989  
 945  990          while (buf[i] != '\0' && buf[i] == ' ')
 946  991                  i++;
 947  992  
 948  993          if (buf[i] == '\0' || strstr(buf, SMB_DEFAULT1) != NULL ||
 949  994              strstr(buf, SMB_DEFAULT2) != NULL)
 950  995                  return (NULL);
 951  996  
 952  997          return (serial);
 953  998  }
 954  999  
 955 1000  /*
 956 1001   * Get chassis SN or product SN
 957 1002   */
 958 1003  static int
 959 1004  smb_get_sn(smbios_hdl_t *shp, const char **psnp, const char **csnp)
 960 1005  {
 961 1006          const smb_struct_t *stp;
 962 1007          smbios_info_t s1, s3;
 963 1008  
 964 1009          if (psnp == NULL || csnp == NULL)
 965 1010                  return (smb_set_errno(shp, ESMB_INVAL));
 966 1011  
 967 1012          *psnp = *csnp = NULL;
 968 1013  
 969 1014          /*
 970 1015           * If SMBIOS meets Sun's PRMS requirements, retrieve product SN
 971 1016           * from type 1 structure, and chassis SN from type 3 structure.
 972 1017           * Otherwise return SN in type 1 structure as chassis SN.
 973 1018           */
 974 1019  
 975 1020          /* Get type 1 SN */
 976 1021          if ((stp = smb_lookup_type(shp, SMB_TYPE_SYSTEM)) == NULL ||
 977 1022              smbios_info_common(shp, stp->smbst_hdr->smbh_hdl, &s1) == SMB_ERR)
 978 1023                  s1.smbi_serial = NULL;
 979 1024  
 980 1025          /* Get type 3 SN */
 981 1026          if ((stp = smb_lookup_type(shp, SMB_TYPE_CHASSIS)) == NULL ||
 982 1027              smbios_info_common(shp, stp->smbst_hdr->smbh_hdl, &s3) == SMB_ERR)
 983 1028                  s3.smbi_serial = NULL;
 984 1029  
 985 1030          if (smbios_has_oemstr(shp, SMB_PRMS1)) {
 986 1031                  *psnp = smb_serial_valid(s1.smbi_serial);
 987 1032                  *csnp = smb_serial_valid(s3.smbi_serial);
 988 1033          } else {
 989 1034                  *csnp = smb_serial_valid(s1.smbi_serial);
 990 1035          }
 991 1036  
 992 1037          return (0);
 993 1038  }
 994 1039  
 995 1040  const char *
 996 1041  smbios_psn(smbios_hdl_t *shp)
 997 1042  {
 998 1043          const char *psn, *csn;
 999 1044  
1000 1045          return (smb_get_sn(shp, &psn, &csn) == SMB_ERR ? NULL : psn);
1001 1046  }
1002 1047  
1003 1048  const char *
1004 1049  smbios_csn(smbios_hdl_t *shp)
1005 1050  {
1006 1051          const char *psn, *csn;
1007 1052  
1008 1053          return (smb_get_sn(shp, &psn, &csn) == SMB_ERR ? NULL : csn);
1009 1054  }
1010 1055  
1011 1056  int
1012 1057  smbios_info_extprocessor(smbios_hdl_t *shp, id_t id,
1013 1058      smbios_processor_ext_t *epp)
1014 1059  {
1015 1060          const smb_struct_t *stp = smb_lookup_id(shp, id);
1016 1061          smb_processor_ext_t *exp;
1017 1062  
1018 1063          if (stp == NULL)
1019 1064                  return (-1); /* errno is set for us */
1020 1065  
1021 1066          if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_PROCESSOR)
1022 1067                  return (smb_set_errno(shp, ESMB_TYPE));
1023 1068  
1024 1069          exp = (smb_processor_ext_t *)(uintptr_t)stp->smbst_hdr;
1025 1070          bzero(epp, sizeof (smbios_processor_ext_t));
1026 1071  
1027 1072          epp->smbpe_processor = exp->smbpre_processor;
1028 1073          epp->smbpe_fru = exp->smbpre_fru;
1029 1074          epp->smbpe_n = exp->smbpre_n;
1030 1075          epp->smbpe_apicid = exp->smbpre_apicid;
1031 1076  
1032 1077          return (0);
1033 1078  }
1034 1079  
1035 1080  int
1036 1081  smbios_info_extport(smbios_hdl_t *shp, id_t id, smbios_port_ext_t *eportp)
1037 1082  {
1038 1083          const smb_struct_t *stp = smb_lookup_id(shp, id);
1039 1084          smb_port_ext_t *ep;
1040 1085  
1041 1086          if (stp == NULL)
1042 1087                  return (-1); /* errno is set for us */
1043 1088  
1044 1089          if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_PORT)
1045 1090                  return (smb_set_errno(shp, ESMB_TYPE));
1046 1091  
1047 1092          ep = (smb_port_ext_t *)(uintptr_t)stp->smbst_hdr;
1048 1093          bzero(eportp, sizeof (smbios_port_ext_t));
1049 1094  
1050 1095          eportp->smbporte_chassis = ep->smbpoe_chassis;
1051 1096          eportp->smbporte_port = ep->smbpoe_port;
1052 1097          eportp->smbporte_dtype = ep->smbpoe_dtype;
1053 1098          eportp->smbporte_devhdl = ep->smbpoe_devhdl;
1054 1099          eportp->smbporte_phy = ep->smbpoe_phy;
1055 1100  
1056 1101          return (0);
1057 1102  }
1058 1103  
1059 1104  int
1060 1105  smbios_info_pciexrc(smbios_hdl_t *shp, id_t id,
1061 1106      smbios_pciexrc_t *rcp)
1062 1107  {
1063 1108          const smb_struct_t *stp = smb_lookup_id(shp, id);
1064 1109          smb_pciexrc_t rc;
1065 1110  
1066 1111          if (stp == NULL)
1067 1112                  return (-1); /* errno is set for us */
1068 1113  
1069 1114          if (stp->smbst_hdr->smbh_type != SUN_OEM_PCIEXRC)
1070 1115                  return (smb_set_errno(shp, ESMB_TYPE));
1071 1116  
1072 1117          smb_info_bcopy(stp->smbst_hdr, &rc, sizeof (rc));
1073 1118          bzero(rcp, sizeof (smbios_pciexrc_t));
1074 1119  
1075 1120          rcp->smbpcie_bb = rc.smbpciexrc_bboard;
1076 1121          rcp->smbpcie_bdf = rc.smbpciexrc_bdf;
1077 1122  
1078 1123          return (0);
1079 1124  }
1080 1125  
1081 1126  int
1082 1127  smbios_info_extmemarray(smbios_hdl_t *shp, id_t id, smbios_memarray_ext_t *emap)
1083 1128  {
1084 1129          const smb_struct_t *stp = smb_lookup_id(shp, id);
1085 1130          smb_memarray_ext_t exma;
1086 1131  
1087 1132          if (stp == NULL)
1088 1133                  return (-1); /* errno is set for us */
1089 1134  
1090 1135          if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_MEMARRAY)
1091 1136                  return (smb_set_errno(shp, ESMB_TYPE));
1092 1137  
1093 1138          smb_info_bcopy(stp->smbst_hdr, &exma, sizeof (exma));
1094 1139          bzero(emap, sizeof (smbios_memarray_ext_t));
1095 1140  
1096 1141          emap->smbmae_ma = exma.smbmarre_ma;
1097 1142          emap->smbmae_comp = exma.smbmarre_component;
1098 1143          emap->smbmae_bdf = exma.smbmarre_bdf;
1099 1144  
1100 1145          return (0);
1101 1146  }
1102 1147  
1103 1148  int
1104 1149  smbios_info_extmemdevice(smbios_hdl_t *shp, id_t id,
1105 1150      smbios_memdevice_ext_t *emdp)
1106 1151  {
1107 1152          const smb_struct_t *stp = smb_lookup_id(shp, id);
1108 1153          smb_memdevice_ext_t exmd;
1109 1154  
1110 1155          if (stp == NULL)
1111 1156                  return (-1); /* errno is set for us */
1112 1157  
1113 1158          if (stp->smbst_hdr->smbh_type != SUN_OEM_EXT_MEMDEVICE)
1114 1159                  return (smb_set_errno(shp, ESMB_TYPE));
1115 1160  
1116 1161          smb_info_bcopy(stp->smbst_hdr, &exmd, sizeof (exmd));
1117 1162          bzero(emdp, sizeof (smbios_memdevice_ext_t));
1118 1163  
1119 1164          emdp->smbmdeve_md = exmd.smbmdeve_mdev;
1120 1165          emdp->smbmdeve_drch = exmd.smbmdeve_dchan;
1121 1166          emdp->smbmdeve_ncs  = exmd.smbmdeve_ncs;
1122 1167          emdp->smbmdeve_cs = exmd.smbmdeve_cs;
1123 1168  
1124 1169          return (0);
1125 1170  }
  
    | 
      ↓ open down ↓ | 
    299 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX