summaryrefslogtreecommitdiff
path: root/usr/src/lib/fm
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/fm')
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c61
-rw-r--r--usr/src/lib/fm/topo/modules/common/ses/ses_facility.c4
-rw-r--r--usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c117
-rw-r--r--usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h4
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c4
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c2
6 files changed, 114 insertions, 78 deletions
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c b/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c
index bb2cf6d344..390017fd4a 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c
@@ -29,27 +29,14 @@
#include <pcibus.h>
#include <topo_sensor.h>
-int
-pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev)
+static const char *pci_sensor_types[] = { "current", "voltage", "temperature" };
+
+static int
+pci_create_dev_scandir(topo_mod_t *mod, tnode_t *dev, const char *path)
{
int ret;
DIR *d;
- char path[PATH_MAX];
- topo_instance_t binst, dinst;
struct dirent *ent;
- tnode_t *parent = topo_node_parent(dev);
-
- binst = topo_node_instance(parent);
- dinst = topo_node_instance(dev);
-
- if (snprintf(path, sizeof (path), "/dev/sensors/temperature/pci/%x.%x",
- binst, dinst) >= sizeof (path)) {
- topo_mod_dprintf(mod, "failed to construct temp sensor "
- "directory path, path too long");
- return (topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM));
- }
-
- topo_mod_dprintf(mod, "searching for sensors in %s", path);
d = opendir(path);
if (d == NULL) {
@@ -72,24 +59,54 @@ pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev)
if (snprintf(spath, sizeof (spath), "%s/%s", path,
ent->d_name) >= sizeof (spath)) {
- topo_mod_dprintf(mod, "failed to construct temp sensor "
- "path for %s/%s, path too long", path, ent->d_name);
+ topo_mod_dprintf(mod, "failed to construct sensor path "
+ "for %s/%s, path too long", path, ent->d_name);
ret = topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM);
goto out;
}
topo_mod_dprintf(mod, "attempting to create sensor at %s",
spath);
- if ((ret = topo_sensor_create_temp_sensor(mod, dev, spath,
+ if ((ret = topo_sensor_create_scalar_sensor(mod, dev, spath,
ent->d_name)) < 0) {
goto out;
}
-
}
+
ret = 0;
out:
(void) closedir(d);
-
return (ret);
}
+
+int
+pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev)
+{
+ uint_t i;
+ char path[PATH_MAX];
+ topo_instance_t binst, dinst;
+ tnode_t *parent = topo_node_parent(dev);
+
+ binst = topo_node_instance(parent);
+ dinst = topo_node_instance(dev);
+
+ for (i = 0; i < ARRAY_SIZE(pci_sensor_types); i++) {
+ int ret;
+
+ if (snprintf(path, sizeof (path), "/dev/sensors/%s/pci/%x.%x",
+ pci_sensor_types[i], binst, dinst) >= sizeof (path)) {
+ topo_mod_dprintf(mod, "failed to construct %s sensor "
+ "directory path, path too long",
+ pci_sensor_types[i]);
+ return (topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM));
+ }
+
+ topo_mod_dprintf(mod, "searching for sensors in %s", path);
+ if ((ret = pci_create_dev_scandir(mod, dev, path)) != 0) {
+ return (ret);
+ }
+ }
+
+ return (0);
+}
diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c
index 2c4a1314e3..faef123480 100644
--- a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c
+++ b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c
@@ -113,7 +113,8 @@ typedef struct ses_sensor_desc {
static const topo_method_t ses_indicator_methods[] = {
{ "ses_indicator_mode", TOPO_PROP_METH_DESC,
TOPO_METH_SES_MODE_VERSION, TOPO_STABILITY_INTERNAL,
- ses_indicator_mode }
+ ses_indicator_mode },
+ { NULL }
};
static const topo_method_t ses_sensor_methods[] = {
@@ -126,6 +127,7 @@ static const topo_method_t ses_sensor_methods[] = {
{ "ses_psu_state", TOPO_PROP_METH_DESC,
TOPO_METH_SES_PSU_VERSION, TOPO_STABILITY_INTERNAL,
ses_psu_state },
+ { NULL }
};
/*
diff --git a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c
index c9e56e9e1f..a716c57a66 100644
--- a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c
+++ b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c
@@ -11,13 +11,14 @@
/*
* Copyright 2019, Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
/*
* This file provides routines to interact with the kernel sensor framework.
* Currently, modules that require interacting with a kernel sensor need to
* build this file as part of the module. This takes care of all the work of
- * setting up and creating the temperature sensor, given a path to that sensor.
+ * setting up and creating the sensor, given a path to that sensor.
*/
#include <sys/types.h>
@@ -31,21 +32,21 @@
#include <sys/fm/protocol.h>
#include <fm/topo_mod.h>
-#define TOPO_METH_TOPO_SENSOR_TEMP "topo_sensor_temp_reading"
-#define TOPO_METH_TOPO_SENSOR_TEMP_DESC "Kernel Temperature Reading"
-#define TOPO_METH_TOPO_SENSOR_TEMP_VERSION 0
+#define TOPO_METH_TOPO_SENSOR_SCALAR "topo_sensor_scalar_reading"
+#define TOPO_METH_TOPO_SENSOR_SCALAR_DESC "Kernel Sensor Scalar Reading"
+#define TOPO_METH_TOPO_SENSOR_SCALAR_VERSION 0
static int
-topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+topo_sensor_scalar_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
nvlist_t *in, nvlist_t **out)
{
int fd = -1, ret;
nvlist_t *args, *nvl;
char *path;
- sensor_ioctl_temperature_t temp;
- double degrees;
+ sensor_ioctl_scalar_t scalar;
+ double value;
- if (vers != TOPO_METH_TOPO_SENSOR_TEMP_VERSION) {
+ if (vers != TOPO_METH_TOPO_SENSOR_SCALAR_VERSION) {
return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
}
@@ -62,31 +63,30 @@ topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
}
- (void) memset(&temp, '\0', sizeof (temp));
- if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) {
- topo_mod_dprintf(mod, "failed to read temperature sensor "
- "%s: %s", path, strerror(errno));
+ (void) memset(&scalar, '\0', sizeof (scalar));
+ if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) {
+ topo_mod_dprintf(mod, "failed to read sensor %s: %s", path,
+ strerror(errno));
ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
goto out;
}
/*
* Check to see if we need to change the value to get it into an
- * accurate reading. Positive values indicate that the temperature
- * reading is in a fractional number of degrees and that each degree
- * contains temp.sit_gran steps. A negative number means that the
- * temperature reading represents temp.sit_gran degrees.
+ * accurate reading. Positive granularities indicate that the sensor
+ * reading is in a fractional number of units and that each unit
+ * contains scalar.sis_gran steps. A negative number means that the
+ * sensor reading represents scalar.sis_gran units.
*/
- degrees = (double)temp.sit_temp;
- if (temp.sit_gran > 1) {
- degrees /= (double)temp.sit_gran;
- } else if (temp.sit_gran < -1) {
- degrees *= (double)labs(temp.sit_gran);
+ value = (double)scalar.sis_value;
+ if (scalar.sis_gran > 1) {
+ value /= (double)scalar.sis_gran;
+ } else if (scalar.sis_gran < -1) {
+ value *= (double)labs(scalar.sis_gran);
}
if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) {
- topo_mod_dprintf(mod, "failed to allocate output temperature "
- "nvl");
+ topo_mod_dprintf(mod, "failed to allocate output nvl");
ret = topo_mod_seterrno(mod, EMOD_NOMEM);
goto out;
}
@@ -94,9 +94,9 @@ topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
if (nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_SENSOR_READING) !=
0 ||
nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != 0 ||
- nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, degrees) != 0) {
+ nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, value) != 0) {
topo_mod_dprintf(mod, "failed to add members to output "
- "temperature nvlist");
+ "sensor nvlist");
nvlist_free(nvl);
ret = topo_mod_seterrno(mod, EMOD_NOMEM);
goto out;
@@ -111,35 +111,40 @@ out:
return (ret);
}
-static const topo_method_t topo_sensor_temp_fac_methods[] = {
- { TOPO_METH_TOPO_SENSOR_TEMP, TOPO_METH_TOPO_SENSOR_TEMP_DESC,
- TOPO_METH_TOPO_SENSOR_TEMP_VERSION, TOPO_STABILITY_INTERNAL,
- topo_sensor_temp_read },
+static const topo_method_t topo_sensor_scalar_fac_methods[] = {
+ { TOPO_METH_TOPO_SENSOR_SCALAR, TOPO_METH_TOPO_SENSOR_SCALAR_DESC,
+ TOPO_METH_TOPO_SENSOR_SCALAR_VERSION, TOPO_STABILITY_INTERNAL,
+ topo_sensor_scalar_read },
{ NULL }
};
static topo_sensor_unit_t
-topo_sensor_units(const sensor_ioctl_temperature_t *temp)
+topo_sensor_units(const sensor_ioctl_scalar_t *scalar)
{
- switch (temp->sit_unit) {
+ switch (scalar->sis_unit) {
case SENSOR_UNIT_CELSIUS:
return (TOPO_SENSOR_UNITS_DEGREES_C);
case SENSOR_UNIT_FAHRENHEIT:
return (TOPO_SENSOR_UNITS_DEGREES_F);
case SENSOR_UNIT_KELVIN:
return (TOPO_SENSOR_UNITS_DEGREES_K);
+ case SENSOR_UNIT_VOLTS:
+ return (TOPO_SENSOR_UNITS_VOLTS);
+ case SENSOR_UNIT_AMPS:
+ return (TOPO_SENSOR_UNITS_AMPS);
default:
return (TOPO_SENSOR_UNITS_UNSPECIFIED);
}
}
int
-topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
+topo_sensor_create_scalar_sensor(topo_mod_t *mod, tnode_t *pnode,
const char *path, const char *fname)
{
int fd, ret, err;
sensor_ioctl_kind_t sik;
- sensor_ioctl_temperature_t temp;
+ sensor_ioctl_scalar_t scalar;
+ uint32_t topo_type;
tnode_t *fnode = NULL;
topo_pgroup_info_t pgi;
nvlist_t *reader_arg = NULL;
@@ -148,16 +153,16 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
topo_node_name(pnode), path);
(void) memset(&sik, '\0', sizeof (sik));
- (void) memset(&temp, '\0', sizeof (temp));
+ (void) memset(&scalar, '\0', sizeof (scalar));
if ((fd = open(path, O_RDONLY)) < 0) {
topo_mod_dprintf(mod, "failed to open sensor path %s: %s",
path, strerror(errno));
/*
- * We always try to create temperature sensors; however, they
- * may not exist or be supported on the system in question.
- * Therefore ENOENT is totally acceptable.
+ * We always try to create sensors; however, they may not exist
+ * or be supported on the system in question. Therefore ENOENT
+ * is totally acceptable.
*/
if (errno == ENOENT) {
return (0);
@@ -165,23 +170,34 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
}
- if (ioctl(fd, SENSOR_IOCTL_TYPE, &sik) != 0) {
+ if (ioctl(fd, SENSOR_IOCTL_KIND, &sik) != 0) {
topo_mod_dprintf(mod, "failed to verify sensor kind for sensor "
"%s: %s", path, strerror(errno));
ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
goto out;
}
- if (sik.sik_kind != SENSOR_KIND_TEMPERATURE) {
- topo_mod_dprintf(mod, "sensor kind for %s is not temperature, "
- "found 0x%x", path, sik.sik_kind);
+ switch (sik.sik_kind) {
+ case SENSOR_KIND_TEMPERATURE:
+ topo_type = TOPO_SENSOR_TYPE_TEMP;
+ break;
+ case SENSOR_KIND_VOLTAGE:
+ topo_type = TOPO_SENSOR_TYPE_VOLTAGE;
+ break;
+ case SENSOR_KIND_CURRENT:
+ topo_type = TOPO_SENSOR_TYPE_CURRENT;
+ break;
+ default:
+ topo_mod_dprintf(mod, "unknown sensor kind for %s, found 0x%x",
+ path, sik.sik_kind);
ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
goto out;
+
}
- if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) {
- topo_mod_dprintf(mod, "failed to read temperature sensor "
- "%s: %s", path, strerror(errno));
+ if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) {
+ topo_mod_dprintf(mod, "failed to read scalar sensor %s: %s",
+ path, strerror(errno));
ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
goto out;
}
@@ -191,7 +207,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
if ((fnode = topo_node_facbind(mod, pnode, fname,
TOPO_FAC_TYPE_SENSOR)) == NULL) {
- topo_mod_dprintf(mod, "failed to bind temperature facility "
+ topo_mod_dprintf(mod, "failed to bind sensor facility "
"node to %s: %d", path, topo_mod_errno(mod));
ret = -1;
goto out;
@@ -213,10 +229,9 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE,
TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 ||
topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
- TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP,
- &err) != 0 ||
+ TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, topo_type, &err) != 0 ||
topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
- TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, topo_sensor_units(&temp),
+ TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, topo_sensor_units(&scalar),
&err) != 0) {
topo_mod_dprintf(mod, "failed to set properties for sensor "
"%s: %s", path, topo_strerror(err));
@@ -225,7 +240,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
}
- if (topo_method_register(mod, fnode, topo_sensor_temp_fac_methods) <
+ if (topo_method_register(mod, fnode, topo_sensor_scalar_fac_methods) <
0) {
topo_mod_dprintf(mod, "failed to register reading methods on "
"%s", path);
@@ -241,7 +256,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
}
if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY,
- TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, TOPO_METH_TOPO_SENSOR_TEMP,
+ TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, TOPO_METH_TOPO_SENSOR_SCALAR,
reader_arg, &err) != 0) {
topo_mod_dprintf(mod, "failed to set argument for sensor %s: "
"%s", path, topo_strerror(err));
@@ -249,6 +264,8 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode,
goto out;
}
+ topo_mod_dprintf(mod, "created sensor at %s", path);
+
nvlist_free(reader_arg);
return (0);
out:
diff --git a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h
index ff6e1ea92e..753dcbd8d8 100644
--- a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h
+++ b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h
@@ -24,8 +24,8 @@
extern "C" {
#endif
-extern int topo_sensor_create_temp_sensor(topo_mod_t *, tnode_t *, const char *,
- const char *);
+extern int topo_sensor_create_scalar_sensor(topo_mod_t *, tnode_t *,
+ const char *, const char *);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c
index 89f8d57fb6..f06190bb46 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c
@@ -71,7 +71,7 @@ chip_create_core_temp_sensor(topo_mod_t *mod, tnode_t *pnode)
}
}
- return (topo_sensor_create_temp_sensor(mod, pnode, buf, "temp"));
+ return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp"));
}
int
@@ -87,5 +87,5 @@ chip_create_chip_temp_sensor(topo_mod_t *mod, tnode_t *pnode)
return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
}
- return (topo_sensor_create_temp_sensor(mod, pnode, buf, "temp"));
+ return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp"));
}
diff --git a/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c b/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c
index cc306b4b2f..2f3781c932 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c
@@ -136,7 +136,7 @@ topo_chipset_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
/*
* Finally, create the temperature sensor.
*/
- if ((ret = topo_sensor_create_temp_sensor(mod, tn,
+ 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");