/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2015 Joyent, Inc.
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* SMBIOS Information Routines
*
* The routines in this file are used to convert from the SMBIOS data format to
* a more reasonable and stable set of structures offered as part of our ABI.
* These functions take the general form:
*
* stp = smb_lookup_type(shp, foo);
* smb_foo_t foo;
*
* smb_info_bcopy(stp->smbst_hdr, &foo, sizeof (foo));
* bzero(caller's struct);
*
*
* We copy the internal structure on to an automatic variable so as to avoid
* checks everywhere for structures that the BIOS has improperly truncated, and
* also to automatically handle the case of a structure that has been extended.
* When necessary, this code can use smb_gteq() to determine whether the SMBIOS
* data is of a particular revision that is supposed to contain a new field.
*
* Note, when trying to bzero the caller's struct you have to be careful about
* versions. One can only bzero the initial version that existed in illumos. In
* other words, if someone passes an older library handle that doesn't support a
* version you cannot assume that their structures have those additional members
* in them. Instead, a 'base' version is introduced for such types that have
* differences and instead we only bzero out the base version and then handle
* the additional members. In general, because all additional members will be
* assigned, there's no reason to zero them out unless they are arrays that
* won't be entirely filled in.
*
* Due to history, anything added after the update from version 2.4, in other
* words additions from or after '5094 Update libsmbios with recent items'
* (4e901881) is currently being used for this. While we don't allow software
* compiling against this to get an older form, this was the first major update
* and a good starting point for us to enforce this behavior which is useful for
* moving forward to making this more public.
*/
#include <sys/smbios_impl.h>
#ifdef _KERNEL
#else
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#endif
/*
* A large number of SMBIOS structures contain a set of common strings used to
* describe a h/w component's serial number, manufacturer, etc. These fields
* helpfully have different names and offsets and sometimes aren't consistent.
* To simplify life for our clients, we factor these common things out into
* smbios_info_t, which can be retrieved for any structure. The following
* table describes the mapping from a given structure to the smbios_info_t.
* Multiple SMBIOS stuctures' contained objects are also handled here.
*/
static const struct smb_infospec {
} _smb_infospecs[] = {
0,
0,
0,
0,
0,
0 },
0,
0,
0,
0,
0,
0,
0,
0 },
0,
0,
0,
0,
0,
0,
0,
0,
0 },
0,
0,
0,
0,
0,
0,
0,
0,
0 },
0,
0,
0,
0,
0,
0,
0,
0,
0 },
0,
0,
0,
0,
0 },
0,
0,
0 },
{ SMB_TYPE_EOT }
};
static const char *
{
(*n)++; /* indicate success for caller */
}
return (smb_strptr(stp, 0));
}
static void
{
} else
}
void
{
}
#ifndef _KERNEL
#endif
int
{
int n = 0;
return (-1); /* errno is set for us */
break;
}
/*
* This private file allows developers to experiment with reporting
* different platform strings from SMBIOS. It is not a supported
* mechanism in the long term, and does not work in the kernel.
*/
#ifndef _KERNEL
if (!smbios_product_checked) {
if (fd >= 0) {
sizeof (smbios_product_override) - 1);
}
}
if (smbios_product_override[0] != '\0')
}
#endif
/*
* If we have a port with an empty internal reference designator string
* try using the external reference designator string instead.
*/
}
}
/*
* Returns the actual number of contained objects.
*
* idc - number of contained objects
* idv - returned array of contained objects
*/
int
{
int i, n;
return (-1); /* errno is set for us */
}
break;
}
for (i = 0; i < n; i++) {
if (size == SMB_CONT_WORD)
else if (size == SMB_CONT_BYTE)
else
}
return (cnt);
}
{
return (-1); /* errno is set for us */
/*
* If one or more extension bytes are present, reset smbb_xcflags to
* point to them. Otherwise leave this member set to NULL.
*/
sizeof (smb_bios_t) + 1;
}
}
}
{
return (-1); /* errno is set for us */
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
/* Length is measurable by one byte, so it'll be no more than 255. */
return (-1); /* errno is set for us */
}
}
return (0);
}
int
{
return (-1); /* errno is set for us */
}
}
return (0);
}
int
{
smb_cache_t c;
return (-1); /* errno is set for us */
if (SMB_CACHE_CFG_ENABLED(c.smbca_config))
if (SMB_CACHE_CFG_SOCKETED(c.smbca_config))
return (0);
}
int
{
smb_port_t p;
return (-1); /* errno is set for us */
return (0);
}
int
{
smb_slot_t s;
return (-1); /* errno is set for us */
return (0);
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
int i, m, n;
return (-1); /* errno is set for us */
}
return (m);
}
/*
* The implementation structures for OEMSTR, SYSCONFSTR, and LANG all use the
* first byte to indicate the size of a string table at the end of the record.
* Therefore, smbios_info_strtab() can be used to retrieve the table size and
* strings for any of these underlying record types.
*/
int
{
smb_strtab_t s;
int i, n;
return (-1); /* errno is set for us */
for (i = 0; i < n; i++)
return (s.smbtb_count);
}
{
smb_lang_t l;
return (-1); /* errno is set for us */
}
{
return (-1); /* errno is set for us */
}
}
int
{
return (-1); /* errno is set for us */
if (m.smbmarr_cap != 0x80000000)
else if (m.smbmarr_extcap != 0)
else
return (0);
}
int
{
return (-1); /* errno is set for us */
} else if (m.smbamap_extstart != 0 && m.smbamap_extend != 0) {
}
return (0);
}
int
{
return (-1); /* errno is set for us */
if (m.smbmdev_size == 0x7FFF) {
} else if (m.smbmdev_size != 0xFFFF) {
if (m.smbmdev_size & SMB_MDS_KBYTES)
else
} else
}
return (0);
}
int
{
return (-1); /* errno is set for us */
} else if (m.smbdmap_extstart != 0 && m.smbdmap_extend != 0) {
}
return (0);
}
{
return (-1); /* errno is set for us */
}
{
return (-1); /* errno is set for us */
}
{
smb_ipmi_t i;
return (-1); /* errno is set for us */
else
if (SMB_IPM_INFO_LSB(i.smbipm_info))
if (i.smbipm_addr & SMB_IPM_ADDR_IO) {
switch (SMB_IPM_INFO_REGS(i.smbipm_info)) {
case SMB_IPM_REGS_1B:
break;
case SMB_IPM_REGS_4B:
break;
case SMB_IPM_REGS_16B:
break;
default:
}
}
if (SMB_IPM_INFO_ISPEC(i.smbipm_info))
}
static boolean_t
{
smb_strtab_t s;
int i, j;
continue;
for (j = 0; j < s.smbtb_count; j++)
return (B_TRUE);
}
return (B_FALSE);
}
static const char *
{
int i = 0;
return (NULL);
i++;
return (NULL);
return (serial);
}
/*
* Get chassis SN or product SN
*/
static int
{
/*
* If SMBIOS meets Sun's PRMS requirements, retrieve product SN
* from type 1 structure, and chassis SN from type 3 structure.
* Otherwise return SN in type 1 structure as chassis SN.
*/
/* Get type 1 SN */
/* Get type 3 SN */
} else {
}
return (0);
}
const char *
{
}
const char *
{
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
return (-1); /* errno is set for us */
return (0);
}
int
{
return (-1); /* errno is set for us */
return (0);
}