diff options
Diffstat (limited to 'usr/src/lib/fm')
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"); |