#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/fm/protocol.h>
#include <fm/topo_mod.h>
#include <fm/topo_list.h>
#include <fm/topo_method.h>
#include <topo_sensor.h>
#define CHIPSET_VERSION 1
static const char *topo_chipset_temp_sensor =
"/dev/sensors/temperature/pch/ts.0";
static boolean_t
topo_chipset_present(void)
{
struct stat st;
if (stat(topo_chipset_temp_sensor, &st) == 0 &&
S_ISCHR(st.st_mode)) {
return (B_TRUE);
}
return (B_FALSE);
}
static int
topo_chipset_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
topo_instance_t min, topo_instance_t max, void *modarg, void *data)
{
int ret;
nvlist_t *fmri = NULL, *auth = NULL, *presource = NULL;
tnode_t *tn = NULL;
const topo_instance_t inst = 0;
topo_mod_dprintf(mod, "chipset_enum: asked to enumerate %s", name);
if (strcmp(name, CHIPSET) != 0) {
topo_mod_dprintf(mod, "chipset_enum: asked to enumerate "
"unknown component");
return (topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM));
}
if (!topo_chipset_present()) {
topo_mod_dprintf(mod, "chipset_enum: no %s device present",
name);
return (0);
}
if ((auth = topo_mod_auth(mod, pnode)) == NULL) {
topo_mod_dprintf(mod, "chipset_enum: failed to get topo "
"auth: %s", topo_mod_errmsg(mod));
ret = -1;
goto err;
}
if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
CHIPSET, inst, NULL, auth, NULL, NULL, NULL)) == NULL) {
topo_mod_dprintf(mod, "chipset_enum: failed to get FMRI: %s",
topo_mod_errmsg(mod));
ret = -1;
goto err;
}
if ((tn = topo_node_bind(mod, pnode, CHIPSET, inst, fmri)) == NULL) {
topo_mod_dprintf(mod, "chipset_enum: failed to bind node: %s",
topo_mod_errmsg(mod));
ret = -1;
goto err;
}
if (topo_node_resource(pnode, &presource, &ret) != 0) {
topo_mod_dprintf(mod, "chipset_enum: failed to get parent "
"resource %s\n", topo_strerror(ret));
ret = topo_mod_seterrno(mod, ret);
goto err;
}
if (topo_node_fru_set(tn, presource, 0, &ret) != 0) {
topo_mod_dprintf(mod, "chipset_enum: failed to set FRU: %s",
topo_strerror(ret));
ret = topo_mod_seterrno(mod, ret);
goto err;
}
if ((ret = topo_sensor_create_scalar_sensor(mod, tn,
topo_chipset_temp_sensor, "temp")) != 0) {
topo_mod_dprintf(mod, "failed to create chipset temperature "
"sensor");
goto err;
}
nvlist_free(auth);
nvlist_free(fmri);
nvlist_free(presource);
return (0);
err:
nvlist_free(auth);
nvlist_free(fmri);
nvlist_free(presource);
topo_node_unbind(tn);
return (ret);
}
static const topo_modops_t chipset_ops = {
topo_chipset_enum, NULL
};
static topo_modinfo_t chipset_mod = {
CHIPSET, FM_FMRI_SCHEME_HC, CHIPSET_VERSION, &chipset_ops
};
int
_topo_init(topo_mod_t *mod, topo_version_t version)
{
if (getenv("TOPOCHIPSETDEBUG") != NULL) {
topo_mod_setdebug(mod);
}
topo_mod_dprintf(mod, "_mod_init: initializing %s enumerator\n",
CHIPSET);
if (version != -1) {
}
if (topo_mod_register(mod, &chipset_mod, TOPO_VERSION) != 0) {
return (-1);
}
return (0);
}
void
_topo_fini(topo_mod_t *mod)
{
}