/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mem.h>
#include <fm/fmd_fmri.h>
#include <fm/fmd_agent.h>
#include <string.h>
#include <strings.h>
static int
{
char *unum;
return (fmd_fmri_set_errno(EINVAL));
return (0);
}
static int
{
return (-1);
return (rc);
}
{
int i;
return (-1); /* errno is set for us */
/*
* If we have a well-formed unum (hc-FMRI), use the string verbatim
* to form the initial mem:/// components. Otherwise use unum=%s.
*/
else
prefix = "";
/*
* If we have a DIMM offset, include it in the string. If we have a PA
* then use that. Otherwise just format the unum element.
*/
"%s:///%s%%1$s/%s=%%2$llx",
"%s:///%s%%1$s/%s=%%2$llx",
} else {
}
/*
* If we have a well-formed unum (hc-FMRI), we skip over the
* the scheme and authority prefix.
* Otherwise, the spaces and colons will be escaped,
* rendering the resulting FMRI pretty much unreadable.
* We're therefore going to do some escaping of our own first.
*/
rawunum += 5;
++rawunum;
/* LINTED: variable format specifier */
} else {
for (i = 0; i < presz - 1; i++) {
presz - (i + 2));
} else if (preunum[i] == ' ') {
preunum[i] = ',';
}
}
/* LINTED: variable format specifier */
}
return (size);
}
int
{
return (fmd_fmri_set_errno(EINVAL));
/*
* If the mem-scheme topology exports this method expand(), invoke it.
*/
return (fmd_fmri_set_errno(EINVAL));
if (err != ETOPO_METHOD_NOTSUP)
return (rc);
return (0);
return (fmd_fmri_set_errno(EINVAL));
/* errno is set for us */
return (0); /* nothing to add - no s/n support */
else
return (-1);
}
nserids);
if (rc != 0)
return (fmd_fmri_set_errno(EINVAL));
else
return (0);
}
#ifdef sparc
static int
{
int i;
return (0);
for (i = 0; i < nserids1; i++) {
return (0);
}
return (1);
}
#endif /* sparc */
int
{
#ifdef sparc
#else
#endif /* sparc */
return (-1); /* errno is set for us */
#ifdef sparc
/*
* If the mem-scheme topology exports this method present(), invoke it.
*/
return (fmd_fmri_set_errno(EINVAL));
if (err != ETOPO_METHOD_NOTSUP)
return (rc);
&nnvlserids) != 0) {
/*
* Some mem scheme FMRIs don't have serial ids because
* either the platform does not support them, or because
* the FMRI was created before support for serial ids was
* introduced. If this is the case, assume it is there.
*/
return (1);
else
return (fmd_fmri_set_errno(EINVAL));
}
return (1); /* assume it's there, no s/n support here */
/*
* Errors are only signalled to the caller if they're
* the caller's fault. This isn't - it's a failure on
* our part to burst or read the serial numbers. We'll
* whine about it, and tell the caller the named
*/
fmd_fmri_warn("failed to retrieve serial number for "
"unum %s", unum);
}
return (0);
}
#else
/*
* On X86 we will invoke the topo is_present method passing in the
* unum, which is in hc scheme. The libtopo hc-scheme is_present method
* will invoke the node-specific is_present method, which is implemented
* by the chip enumerator for rank nodes. The rank node's is_present
* method will compare the serial number in the unum with the current
* serial to determine if the same DIMM is present.
*/
fmd_fmri_warn("failed to get handle to topology");
return (-1);
}
} else
/*
* Need to check if this is a valid page too. if "isretired" returns
* EINVAL, assume page invalid and return not_present.
*/
rc = 0;
}
#endif /* sparc */
return (rc);
}
int
{
#ifdef sparc
#else
#endif /* sparc */
return (-1); /* errno is set for us */
#ifdef sparc
/*
* If the mem-scheme topology exports this method replaced(), invoke it.
*/
return (fmd_fmri_set_errno(EINVAL));
if (err != ETOPO_METHOD_NOTSUP)
return (rc);
&nnvlserids) != 0) {
/*
* Some mem scheme FMRIs don't have serial ids because
* either the platform does not support them, or because
* the FMRI was created before support for serial ids was
* introduced. If this is the case, assume it is there.
*/
return (FMD_OBJ_STATE_UNKNOWN);
else
return (fmd_fmri_set_errno(EINVAL));
}
return (FMD_OBJ_STATE_UNKNOWN);
/*
* Errors are only signalled to the caller if they're
* the caller's fault. This isn't - it's a failure on
* our part to burst or read the serial numbers. We'll
* whine about it, and tell the caller the named
*/
fmd_fmri_warn("failed to retrieve serial number for "
"unum %s", unum);
}
return (FMD_OBJ_STATE_NOT_PRESENT);
}
#else
/*
* On X86 we will invoke the topo is_replaced method passing in the
* unum, which is in hc scheme. The libtopo hc-scheme is_replaced
* method will invoke the node-specific is_replaced method, which is
* implemented by the chip enumerator for rank nodes. The rank node's
* is_replaced method will compare the serial number in the unum with
* the current serial to determine if the same DIMM is replaced.
*/
fmd_fmri_warn("failed to get handle to topology");
return (-1);
}
} else
/*
* Need to check if this is a valid page too. if "isretired" returns
* EINVAL, assume page invalid and return not_present.
*/
if ((rc == FMD_OBJ_STATE_STILL_PRESENT ||
rc == FMD_OBJ_STATE_UNKNOWN) &&
}
#endif /* sparc */
return (rc);
}
int
{
/*
* If the mem-scheme topology exports this method contains(), invoke it.
*/
return (fmd_fmri_set_errno(EINVAL));
if (err != ETOPO_METHOD_NOTSUP)
return (rc);
return (-1); /* errno is set for us */
return (nvlist_lookup_uint64(ee,
}
return (nvlist_lookup_uint64(ee,
}
return (1);
}
/*
* without page addresses will be reported as usable since Solaris has no
* way at present to dynamically disable an entire DIMM or DIMM pair.
*/
int
{
int retval;
return (fmd_fmri_set_errno(EINVAL));
/*
* If the mem-scheme topology exports this method unusable(), invoke it.
*/
return (fmd_fmri_set_errno(EINVAL));
if (err1 != ETOPO_METHOD_NOTSUP)
return (rc);
return (0); /* no page, so assume it's still usable */
return (fmd_fmri_set_errno(EINVAL));
return (fmd_fmri_set_errno(rc));
/*
* Ask the kernel if the page is retired, using either the rewritten
* hc FMRI or the original mem FMRI with the specified offset or PA.
* Refer to the kernel's page_retire_check() for the error codes.
*/
if (rc == FMD_AGENT_RETIRE_FAIL) {
/*
* The page is not retired and is not scheduled for retirement
* (i.e. no request pending and has not seen any errors)
*/
retval = 0;
} else if (rc == FMD_AGENT_RETIRE_DONE ||
rc == FMD_AGENT_RETIRE_ASYNC) {
/*
* The page has been retired, is in the process of being
* retired, or doesn't exist. The latter is valid if the page
* existed in the past but has been DR'd out.
*/
retval = 1;
} else {
/*
* Errors are only signalled to the caller if they're the
* caller's fault. This isn't - it's a failure of the
* retirement-check code. We'll whine about it and tell
* the caller the page is unusable.
*/
fmd_fmri_warn("failed to determine page %s=%llx usability: "
retval = 1;
}
return (retval);
}
int
fmd_fmri_init(void)
{
return (mem_discover());
}
void
fmd_fmri_fini(void)
{
}
}
}
}
}