/*
* 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
*/
/*
*/
/*
* Support function for the i86pc chip enumerator
*/
#include <stdarg.h>
#include <strings.h>
#include <fm/fmd_fmri.h>
#include <sys/systeminfo.h>
#include <fm/topo_mod.h>
#include <fm/fmd_agent.h>
#include "chip.h"
{ NULL }
};
/*
* Whinge a debug message via topo_mod_dprintf and increment the
* given error counter.
*/
void
{
++*nerr;
}
/*
* Given an nvpair of a limited number of data types, extract the property
* name and value and add that combination to the given node in the
* specified property group using the corresponding topo_prop_set_* function
* for the data type. Return 1 on success, otherwise 0.
*/
int
{
int success = 0;
int err;
switch (nvpair_type(nvp)) {
case DATA_TYPE_BOOLEAN_VALUE: {
success = 1;
break;
}
case DATA_TYPE_UINT32: {
success = 1;
break;
}
case DATA_TYPE_UINT64: {
success = 1;
break;
}
case DATA_TYPE_UINT32_ARRAY: {
success = 1;
break;
}
case DATA_TYPE_STRING: {
char *str;
success = 1;
break;
}
default:
"'%s' in property group %s of %s node\n",
break;
}
return (success ? 0 : 1);
}
/*
* Lookup string data named pname in the given nvlist and add that
* as property named pname in the given property group pgname on the indicated
* topo node. Fill pvalp with a pointer to the string value, valid until
* nvlist_free is called.
*/
int
{
char *pval;
int err = 0;
return (-1);
if (pvalp)
return (0);
} else {
pname);
return (-1);
}
}
/*
* Lookup an int32 item named pname in the given nvlist and add that
* as property named pname in the given property group pgname on the indicated
* topo node. Fill pvalp with the property value.
*/
int
{
int err;
return (-1);
if (pvalp)
return (0);
} else {
pname);
return (-1);
}
}
/*
* In a given nvlist lookup a variable number of int32 properties named in
* const char * varargs and each each in the given property group on the
* node. Fill an array of the retrieved values.
*/
int
{
const char *pname;
int nerr = 0;
pvalap) != 0)
nerr++; /* have whinged elsewhere */
++pvalap;
}
return (nerr == 0 ? 0 : -1);
}
/*
* Construct an hc scheme resource FMRI for a node named name with
* instance number inst, parented by the given parent node pnode.
*/
int
{
}
/*
* Construct a cpu scheme FMRI with the given data; the caller must free
* the allocated nvlist with nvlist_free().
*/
nvlist_t *
{
int err;
return (NULL);
if (s != NULL)
if (err != 0) {
return (NULL);
}
return (asru);
}
/*ARGSUSED*/
int
{
int err;
} else {
}
}
err = 0;
/*
* if 'in' includes an hc-specific member which specifies asru-physaddr
* or asru-offset then rename them to asru and physaddr respectively.
*/
if (nvlist_lookup_uint64(hcsp,
"asru-"FM_FMRI_HC_SPECIFIC_PHYSADDR,
pa);
}
if (nvlist_lookup_uint64(hcsp,
"asru-"FM_FMRI_HC_SPECIFIC_OFFSET,
offset);
}
}
}
if (err != 0) {
nvlist_free(*out);
}
return (0);
}
static int
{
}
return (0);
}
/*
* If we're getting called then the question of whether this dimm is plugged
* in has already been answered. What we don't know for sure is whether it's
* the same dimm or a different one plugged in the same slot. To check, we
* try and compare the serial numbers on the dimm in the current topology with
* the serial num from the unum fmri that got passed into this function as the
* argument.
*
*/
static int
{
int err;
/*
* If a serial number for the dimm was available at the time of the
* fault, it will have been added as a string to the unum nvlist
*/
return (FMD_OBJ_STATE_UNKNOWN);
/*
* If the current serial number is available for the DIMM that this rank
* belongs to, it will be accessible as a property on the parent (dimm)
* node. If there is a serial id in the resource fmri, then use that.
* Otherwise fall back to looking for a serial id property in the
* protocol group.
*/
&curr_serial) == 0 ||
&curr_serial) == 0) {
return (FMD_OBJ_STATE_REPLACED);
} else {
return (FMD_OBJ_STATE_STILL_PRESENT);
}
}
}
if (err == ETOPO_PROP_NOENT) {
return (FMD_OBJ_STATE_UNKNOWN);
} else {
*errp = EMOD_NVL_INVAL;
"error retrieving serial from node");
return (-1);
}
}
return (FMD_OBJ_STATE_REPLACED);
}
return (FMD_OBJ_STATE_STILL_PRESENT);
}
int
{
if (presence_state == -1)
}
static void
{
char *fmristr;
const char *status;
return;
switch (rc) {
case FMD_AGENT_RETIRE_DONE:
status = "sync success";
break;
case FMD_AGENT_RETIRE_ASYNC:
status = "async retiring";
break;
case FMD_AGENT_RETIRE_FAIL:
status = "not retired";
break;
default:
status = "unknown status";
}
}
}
struct strand_walk_data {
int err;
int done;
int fail;
int async;
};
static int
{
/*
* Terminate the walk if we reach start-node's sibling
*/
return (TOPO_WALK_TERMINATE);
return (TOPO_WALK_NEXT);
return (TOPO_WALK_NEXT);
}
if (rc == FMD_AGENT_RETIRE_DONE)
else if (rc == FMD_AGENT_RETIRE_FAIL)
else if (rc == FMD_AGENT_RETIRE_ASYNC)
else
const char *op;
op = "retire";
op = "unretire";
op = "check status";
else
op = "unknown op";
}
return (TOPO_WALK_NEXT);
}
static int
int (*func)(fmd_agent_hdl_t *, int, int, int))
{
int err;
return (0);
}
return (-1);
}
return (-1);
return (0);
}
/* ARGSUSED */
int
{
if (version > TOPO_METH_RETIRE_VERSION)
return (-1);
else
}
/* ARGSUSED */
int
{
return (-1);
else
}
/* ARGSUSED */
int
{
return (-1);
else
}
static boolean_t
{
&val) == 0 ||
&val) == 0 ||
&val) == 0 ||
&val) == 0))
return (B_TRUE);
return (B_FALSE);
}
/* ARGSUSED */
int
{
if (version > TOPO_METH_RETIRE_VERSION)
if (is_page_fmri(in)) {
}
}
}
/* ARGSUSED */
int
{
if (is_page_fmri(in)) {
}
}
}
/* ARGSUSED */
int
{
if (is_page_fmri(in)) {
if (rc == FMD_AGENT_RETIRE_DONE)
else if (rc == FMD_AGENT_RETIRE_FAIL)
else if (rc == FMD_AGENT_RETIRE_ASYNC)
}
}
}