Ejemplo n.º 1
0
/* callback function invoked from OpenIPMI */
static void	got_thresh_reading(ipmi_sensor_t *sensor, int err, enum ipmi_value_present_e value_present,
		unsigned int raw_value, double val, ipmi_states_t *states, void *cb_data)
{
	const char		*__function_name = "got_thresh_reading";
	char			id_str[2 * IPMI_SENSOR_ID_SZ + 1];
	const char		*e_string, *s_type_string, *s_reading_type_string;
	ipmi_entity_t		*ent;
	const char		*percent = "", *base, *mod_use = "", *modifier = "", *rate;
	zbx_ipmi_host_t		*h = cb_data;
	zbx_ipmi_sensor_t	*s;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (0 != err)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() fail: %s", __function_name, zbx_strerror(err));

		h->err = zbx_dsprintf(h->err, "error 0x%x while reading threshold sensor", err);
		h->ret = NETWORK_ERROR;
		h->done = 1;
		goto out;
	}

	s = get_ipmi_sensor(h, sensor);

	if (NULL == s)
	{
		THIS_SHOULD_NEVER_HAPPEN;
		h->err = zbx_dsprintf(h->err, "fatal error");
		h->ret = NOTSUPPORTED;
		h->done = 1;
		goto out;
	}

	switch (value_present)
	{
		case IPMI_NO_VALUES_PRESENT:
		case IPMI_RAW_VALUE_PRESENT:
			h->err = zbx_dsprintf(h->err, "no value present for threshold sensor");
			h->ret = NOTSUPPORTED;
			break;
		case IPMI_BOTH_VALUES_PRESENT:
			s->value.threshold = val;

			/* next lines only for debug logging */
			ent = ipmi_sensor_get_entity(sensor);
			e_string = ipmi_entity_get_entity_id_string(ent);
			s_type_string = ipmi_sensor_get_sensor_type_string(sensor);
			s_reading_type_string = ipmi_sensor_get_event_reading_type_string(sensor);

			base = ipmi_sensor_get_base_unit_string(sensor);
			if (ipmi_sensor_get_percentage(sensor))
				percent = "%";
			switch (ipmi_sensor_get_modifier_unit_use(sensor))
			{
				case IPMI_MODIFIER_UNIT_NONE:
					break;
				case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
					mod_use = "/";
					modifier = ipmi_sensor_get_modifier_unit_string(sensor);
					break;
				case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
					mod_use = "*";
					modifier = ipmi_sensor_get_modifier_unit_string(sensor);
					break;
			}
			rate = ipmi_sensor_get_rate_unit_string(sensor);

			zabbix_log(LOG_LEVEL_DEBUG, "Value [%s | %s | %s | %s | " ZBX_FS_DBL "%s %s%s%s%s]",
					sensor_id_to_str(id_str, sizeof(id_str), s->id, s->id_type, s->id_sz),
					e_string, s_type_string, s_reading_type_string, val, percent, base,
					mod_use, modifier, rate);
			break;
	}
	h->done = 1;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(h->ret));
}
Ejemplo n.º 2
0
static void add_sensor_event_data_format(ipmi_sensor_t		*sensor,
					 SaHpiSensorRecT	*rec)
{
	SaHpiSensorRangeFlagsT temp = 0;
	
	/* Depends on IPMI */
	if (rec->Category == SAHPI_EC_THRESHOLD)
		rec->DataFormat.ReadingFormats = SAHPI_SRF_RAW |
						 SAHPI_SRF_INTERPRETED;
	else
		rec->DataFormat.ReadingFormats = SAHPI_SRF_EVENT_STATE;
	
	/*No info about IsNumeric in IPMI */
	rec->DataFormat.IsNumeric = SAHPI_TRUE;
	rec->DataFormat.SignFormat = (SaHpiSensorSignFormatT)
		ipmi_sensor_get_analog_data_format(sensor);
	rec->DataFormat.BaseUnits = (SaHpiSensorUnitsT)
		ipmi_sensor_get_base_unit(sensor);
	rec->DataFormat.ModifierUnits = (SaHpiSensorUnitsT)
		ipmi_sensor_get_modifier_unit(sensor);
	rec->DataFormat.ModifierUse = (SaHpiSensorModUnitUseT)
		ipmi_sensor_get_modifier_unit_use(sensor);
	
	rec->DataFormat.FactorsStatic = SAHPI_TRUE;
	/* We use first...*/
	rec->DataFormat.Factors.M_Factor = (SaHpiInt16T)
		ipmi_sensor_get_raw_m(sensor, 0);
	rec->DataFormat.Factors.B_Factor = (SaHpiInt16T)
		ipmi_sensor_get_raw_b(sensor, 0);
	rec->DataFormat.Factors.AccuracyFactor = (SaHpiUint16T)
		ipmi_sensor_get_raw_accuracy(sensor, 0);
	rec->DataFormat.Factors.ToleranceFactor = (SaHpiUint8T)
		ipmi_sensor_get_raw_tolerance(sensor, 0);
	rec->DataFormat.Factors.ExpA = (SaHpiUint8T)
		ipmi_sensor_get_raw_accuracy_exp(sensor, 0);
	rec->DataFormat.Factors.ExpR = (SaHpiUint8T)
		ipmi_sensor_get_raw_r_exp(sensor, 0);
	rec->DataFormat.Factors.ExpB = (SaHpiUint8T)
		ipmi_sensor_get_raw_b_exp(sensor, 0);
	rec->DataFormat.Factors.Linearization = (SaHpiSensorLinearizationT)
		ipmi_sensor_get_linearization(sensor);
	
	rec->DataFormat.Percentage = (SaHpiBoolT)
		ipmi_sensor_get_percentage(sensor);

	temp |= SAHPI_SRF_MAX | SAHPI_SRF_MIN;	
	rec->DataFormat.Range.Max.ValuesPresent = SAHPI_SRF_RAW;
	rec->DataFormat.Range.Max.Raw = (SaHpiUint32T)
		ipmi_sensor_get_raw_sensor_max(sensor);
	
	rec->DataFormat.Range.Min.ValuesPresent = SAHPI_SRF_RAW;
	rec->DataFormat.Range.Max.Raw = (SaHpiUint32T)
		ipmi_sensor_get_raw_sensor_min(sensor);
		
	if (ipmi_sensor_get_nominal_reading_specified(sensor)) {
		rec->DataFormat.Range.Nominal.ValuesPresent = SAHPI_SRF_RAW;
		rec->DataFormat.Range.Nominal.Raw = (SaHpiUint32T)
			ipmi_sensor_get_raw_nominal_reading(sensor);
		temp |= SAHPI_SRF_NOMINAL;
	}

	if (ipmi_sensor_get_normal_max_specified(sensor)) {
		rec->DataFormat.Range.NormalMax.ValuesPresent = SAHPI_SRF_RAW;
		rec->DataFormat.Range.NormalMax.Raw = (SaHpiUint32T)
			ipmi_sensor_get_raw_normal_max(sensor);
		temp |= SAHPI_SRF_NORMAL_MAX;
	}
	
	if (ipmi_sensor_get_normal_min_specified(sensor)) {
		rec->DataFormat.Range.NormalMin.ValuesPresent = SAHPI_SRF_RAW;
		rec->DataFormat.Range.NormalMin.Raw = (SaHpiUint32T)
			ipmi_sensor_get_raw_normal_min(sensor);
		temp |= SAHPI_SRF_NORMAL_MIN;
	}	
	rec->DataFormat.Range.Flags = temp;
}
Ejemplo n.º 3
0
static void
sensor_dump(ipmi_sensor_t *sensor, ipmi_cmd_info_t *cmd_info)
{
    ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
    int             num, lun;
    char            *str;
    const char      *cstr;
    int             event_support;
    int             event_reading_type;
    int             len;
    int             rv;
    int             val;

    event_reading_type = ipmi_sensor_get_event_reading_type(sensor);

    ipmi_sensor_get_num(sensor, &lun, &num);
    ipmi_cmdlang_out_int(cmd_info, "LUN", lun);
    ipmi_cmdlang_out_int(cmd_info, "Number", num);
    ipmi_cmdlang_out_int(cmd_info, "Event Reading Type",
		     ipmi_sensor_get_event_reading_type(sensor));
    ipmi_cmdlang_out(cmd_info, "Event Reading Type Name",
		     ipmi_sensor_get_event_reading_type_string(sensor));
    ipmi_cmdlang_out_int(cmd_info, "Type",
			 ipmi_sensor_get_sensor_type(sensor));
    ipmi_cmdlang_out(cmd_info, "Type Name",
		     ipmi_sensor_get_sensor_type_string(sensor));
    val = ipmi_sensor_get_sensor_direction(sensor);
    if (val != IPMI_SENSOR_DIRECTION_UNSPECIFIED)
	ipmi_cmdlang_out(cmd_info, "Direction",
			 ipmi_get_sensor_direction_string(val));
    
    event_support = ipmi_sensor_get_event_support(sensor);
    switch (event_support) {
    case IPMI_EVENT_SUPPORT_PER_STATE:
	ipmi_cmdlang_out(cmd_info, "Event Support", "per state");
	break;
    case IPMI_EVENT_SUPPORT_ENTIRE_SENSOR:
	ipmi_cmdlang_out(cmd_info, "Event Support", "entire sensor");
	break;
    case IPMI_EVENT_SUPPORT_GLOBAL_ENABLE:
	ipmi_cmdlang_out(cmd_info, "Event Support", "global");
	break;
    default:
	break;
    }

    ipmi_cmdlang_out_bool(cmd_info, "Init Scanning",
			 ipmi_sensor_get_sensor_init_scanning(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Events",
			 ipmi_sensor_get_sensor_init_events(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Thresholds",
			 ipmi_sensor_get_sensor_init_thresholds(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Hysteresis",
			 ipmi_sensor_get_sensor_init_hysteresis(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Type",
			 ipmi_sensor_get_sensor_init_type(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Power Up Events",
			 ipmi_sensor_get_sensor_init_pu_events(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Init Power Up Scanning",
			 ipmi_sensor_get_sensor_init_pu_scanning(sensor));

    ipmi_cmdlang_out_bool(cmd_info, "Ignore If No Entity",
			 ipmi_sensor_get_ignore_if_no_entity(sensor));
    ipmi_cmdlang_out_bool(cmd_info, "Auto Rearm",
			 ipmi_sensor_get_supports_auto_rearm(sensor));
    ipmi_cmdlang_out_int(cmd_info, "OEM1",
			 ipmi_sensor_get_oem1(sensor));

    len = ipmi_sensor_get_id_length(sensor);
    if (len) {
	str = ipmi_mem_alloc(len);
	if (!str) {
	    cmdlang->err = ENOMEM;
	    cmdlang->errstr = "Out of memory";
	    goto out_err;
	}
	len = ipmi_sensor_get_id(sensor, str, len);
	ipmi_cmdlang_out_type(cmd_info, "Id",
			      ipmi_sensor_get_id_type(sensor),
			      str, len);
	ipmi_mem_free(str);
    }

    if (event_reading_type == IPMI_EVENT_READING_TYPE_THRESHOLD) {
	int access = ipmi_sensor_get_threshold_access(sensor);
	enum ipmi_thresh_e          thresh;
	enum ipmi_event_value_dir_e value_dir;
	enum ipmi_event_dir_e       dir;
	int                         rv;
	char                        th_name[50];
	double                      dval;

	ipmi_cmdlang_out(cmd_info, "Threshold Access",
			 ipmi_get_threshold_access_support_string(access));

	for (thresh = IPMI_LOWER_NON_CRITICAL;
	     thresh <= IPMI_UPPER_NON_RECOVERABLE; 
	     thresh++)
	{
	    rv = ipmi_sensor_threshold_reading_supported(sensor, thresh, &val);
	    if ((rv) || !val)
		continue;

	    ipmi_cmdlang_out(cmd_info, "Threshold", NULL);
	    ipmi_cmdlang_down(cmd_info);
	    ipmi_cmdlang_out(cmd_info, "Name",
			     ipmi_get_threshold_string(thresh));
	    rv = ipmi_sensor_threshold_readable(sensor, thresh, &val);
	    if (rv)
		val = 0;
	    ipmi_cmdlang_out_bool(cmd_info, "Readable", val);
	    rv = ipmi_sensor_threshold_settable(sensor, thresh, &val);
	    if (rv)
		val = 0;
	    ipmi_cmdlang_out_bool(cmd_info, "Settable", val);

	    for (value_dir = IPMI_GOING_LOW;
		 value_dir <= IPMI_GOING_HIGH;
		 value_dir++)
	    {
		for (dir = IPMI_ASSERTION;
		     dir <= IPMI_DEASSERTION;
		     dir++)
		{
		    rv = ipmi_sensor_threshold_event_supported(sensor,
							       thresh,
							       value_dir,
							       dir,
							       &val);
		    if (rv || !val) continue;

		    snprintf(th_name, sizeof(th_name), "%s %s",
			     ipmi_get_value_dir_string(value_dir),
			     ipmi_get_event_dir_string(dir));
		    ipmi_cmdlang_out(cmd_info, "Supports", th_name);
		}
	    }
	    ipmi_cmdlang_up(cmd_info);
	}

	val = ipmi_sensor_get_hysteresis_support(sensor);
	ipmi_cmdlang_out(cmd_info, "Hysteresis Support",
			 ipmi_get_hysteresis_support_string(val));

#if 0
	/* FIXME - no accuracy handling */
	int ipmi_sensor_get_accuracy(ipmi_sensor_t *sensor, int val,
				     double *accuracy);
#endif

	rv = ipmi_sensor_get_nominal_reading(sensor, &dval);
	if (!rv)
	    ipmi_cmdlang_out_double(cmd_info, "Nominal Reading", dval);
	rv = ipmi_sensor_get_normal_max(sensor, &dval);
	if (!rv)
	    ipmi_cmdlang_out_double(cmd_info, "Normal Max", dval);
	rv = ipmi_sensor_get_normal_min(sensor, &dval);
	if (!rv)
	    ipmi_cmdlang_out_double(cmd_info, "Normal Min", dval);
	rv = ipmi_sensor_get_sensor_max(sensor, &dval);
	if (!rv)
	    ipmi_cmdlang_out_double(cmd_info, "Sensor Max", dval);
	rv = ipmi_sensor_get_sensor_min(sensor, &dval);
	if (!rv)
	    ipmi_cmdlang_out_double(cmd_info, "Sensor Min", dval);

	ipmi_cmdlang_out_int(cmd_info, "Base Unit",
			     ipmi_sensor_get_base_unit(sensor));
	ipmi_cmdlang_out(cmd_info, "Base Unit Name",
			 ipmi_sensor_get_base_unit_string(sensor));
	cstr = ipmi_sensor_get_rate_unit_string(sensor);
	if (strlen(cstr)) {
	    ipmi_cmdlang_out_int(cmd_info, "Rate Unit",
				 ipmi_sensor_get_rate_unit(sensor));
	    ipmi_cmdlang_out(cmd_info, "Rate Unit Name", cstr);
	}
	switch (ipmi_sensor_get_modifier_unit_use(sensor)) {
	case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
	    ipmi_cmdlang_out(cmd_info, "Modifier Use", "/");
	    ipmi_cmdlang_out_int(cmd_info, "Modifier Unit",
				 ipmi_sensor_get_modifier_unit(sensor));
	    ipmi_cmdlang_out(cmd_info, "Modifier Unit Name",
			     ipmi_sensor_get_modifier_unit_string(sensor));
	    break;
		
	case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
	    ipmi_cmdlang_out(cmd_info, "Modifier Use", "*");
	    ipmi_cmdlang_out_int(cmd_info, "Modifier Unit",
				 ipmi_sensor_get_modifier_unit(sensor));
	    ipmi_cmdlang_out(cmd_info, "Modifier Unit Name",
			     ipmi_sensor_get_modifier_unit_string(sensor));
	    break;

	default:
	    break;
	}
	if (ipmi_sensor_get_percentage(sensor))
	    ipmi_cmdlang_out(cmd_info, "Percentage", "%");
    } else {
	int                   event;
	enum ipmi_event_dir_e dir;

	for (event=0; event<15; event++) {
	    rv = ipmi_sensor_discrete_event_readable(sensor, event, &val);
	    if (rv || !val)
		continue;
	    ipmi_cmdlang_out(cmd_info, "Event", NULL);
	    ipmi_cmdlang_down(cmd_info);
	    ipmi_cmdlang_out_int(cmd_info, "Offset", event);
	    cstr = ipmi_sensor_reading_name_string(sensor, event);
	    if (strcmp(cstr, "unknown") != 0)
		ipmi_cmdlang_out(cmd_info, "Name", cstr);
	    
	    for (dir = IPMI_ASSERTION;
		 dir <= IPMI_DEASSERTION;
		 dir++)
	    {
		rv = ipmi_sensor_discrete_event_supported(sensor,
							  event,
							  dir,
							  &val);
		if (rv || !val) continue;

		ipmi_cmdlang_out(cmd_info, "Supports",
				 ipmi_get_event_dir_string(dir));
	    }
	    ipmi_cmdlang_up(cmd_info);
	}
    }
    return;

 out_err:
    ipmi_sensor_get_name(sensor, cmdlang->objstr,
			 cmdlang->objstr_len);
    cmdlang->location = "cmd_sensor.c(sensor_dump)";
}
Ejemplo n.º 4
0
static void add_sensor_event_data_format(ipmi_sensor_t		*sensor,
					 SaHpiSensorRecT	*rec)
{
#define FILL_READING(reading, val)                                         \
	do {                                                               \
		(reading).IsSupported = SAHPI_TRUE;                        \
		(reading).Type = SAHPI_SENSOR_READING_TYPE_FLOAT64;        \
		(reading).Value.SensorFloat64 = (SaHpiFloat64T)val;        \
	} while (0)
	int rv;	
	double accur = 0;
	double fval = 0;
	
	rec->DataFormat.IsSupported = SAHPI_TRUE;
	
	rec->DataFormat.ReadingType = SAHPI_SENSOR_READING_TYPE_FLOAT64;	

	rec->DataFormat.BaseUnits = (SaHpiSensorUnitsT)
		ipmi_sensor_get_base_unit(sensor);
	rec->DataFormat.ModifierUnits = (SaHpiSensorUnitsT)
		ipmi_sensor_get_modifier_unit(sensor);
	rec->DataFormat.ModifierUse = (SaHpiSensorModUnitUseT)
		ipmi_sensor_get_modifier_unit_use(sensor);
	
	ipmi_sensor_get_accuracy(sensor, 0, &accur);
	rec->DataFormat.AccuracyFactor = (SaHpiFloat64T)accur;

	rec->DataFormat.Percentage = (SaHpiBoolT)
		ipmi_sensor_get_percentage(sensor);

	rec->DataFormat.Range.Flags = 0;

	rv = ipmi_sensor_get_sensor_max(sensor, &fval);
	if (!rv) {
		FILL_READING(rec->DataFormat.Range.Max, fval);
		rec->DataFormat.Range.Flags |= SAHPI_SRF_MAX;
	}

	rv = ipmi_sensor_get_sensor_min(sensor, &fval);
	if (!rv) {
		FILL_READING(rec->DataFormat.Range.Min, fval);
		rec->DataFormat.Range.Flags |= SAHPI_SRF_MIN;
	}	

	if (ipmi_sensor_get_nominal_reading_specified(sensor)) {
		rv = ipmi_sensor_get_nominal_reading(sensor, &fval);
		if (!rv) {
			FILL_READING(rec->DataFormat.Range.Nominal, fval);
			rec->DataFormat.Range.Flags |= SAHPI_SRF_NOMINAL;
		}
	}
	if (ipmi_sensor_get_normal_max_specified(sensor)) {
		rv = ipmi_sensor_get_normal_max(sensor, &fval);
		if (!rv) {
			FILL_READING(rec->DataFormat.Range.NormalMax, fval);
			rec->DataFormat.Range.Flags |= SAHPI_SRF_NORMAL_MAX;
		}
	}
	
	if (ipmi_sensor_get_normal_min_specified(sensor)) {
		rv = ipmi_sensor_get_normal_min(sensor, &fval);
		if (!rv) {
			FILL_READING(rec->DataFormat.Range.NormalMin, fval);
			rec->DataFormat.Range.Flags |= SAHPI_SRF_NORMAL_MIN;
		}
	}	
}
Ejemplo n.º 5
0
static void	got_thresh_reading(ipmi_sensor_t *sensor, int err, enum ipmi_value_present_e value_present,
		unsigned int raw_value, double val, ipmi_states_t *states, void *cb_data)
{
	const char		*e_string, *s_type_string, *s_reading_type_string;
	ipmi_entity_t		*ent;
	const char		*percent = "", *base, *mod_use = "", *modifier = "", *rate;
	zbx_ipmi_host_t	*h = cb_data;
	zbx_ipmi_sensor_t	*s;

	zabbix_log(LOG_LEVEL_DEBUG, "In got_thresh_reading()");

	if (err) {
		h->err = zbx_dsprintf(h->err, "Error 0x%x while read threshold sensor", err);
		h->ret = NETWORK_ERROR;
		h->done = 1;
		return;
	}

	s = get_ipmi_sensor(h, sensor);

	if (NULL == s)
	{
		/* this should never happen */
		h->err = zbx_dsprintf(h->err, "Fatal error");
		h->ret = NOTSUPPORTED;
		h->done = 1;
		return;
	}

	switch (value_present)
	{
		case IPMI_NO_VALUES_PRESENT:
		case IPMI_RAW_VALUE_PRESENT:
			h->err = zbx_dsprintf(h->err, "No value present for threshold sensor");
			h->ret = NOTSUPPORTED;
			break;
		case IPMI_BOTH_VALUES_PRESENT:
			s->value = val;

			/* next lines only for debug logging */
			ent = ipmi_sensor_get_entity(sensor);
			e_string = ipmi_entity_get_entity_id_string(ent);
			s_type_string = ipmi_sensor_get_sensor_type_string(sensor);
			s_reading_type_string = ipmi_sensor_get_event_reading_type_string(sensor);

			base = ipmi_sensor_get_base_unit_string(sensor);
			if (ipmi_sensor_get_percentage(sensor))
				percent = "%";
			switch (ipmi_sensor_get_modifier_unit_use(sensor)) {
				case IPMI_MODIFIER_UNIT_NONE:
					break;
				case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
					mod_use = "/";
					modifier = ipmi_sensor_get_modifier_unit_string(sensor);
					break;
				case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
					mod_use = "*";
					modifier = ipmi_sensor_get_modifier_unit_string(sensor);
					break;
			}
			rate = ipmi_sensor_get_rate_unit_string(sensor);

			zabbix_log(LOG_LEVEL_DEBUG, "Value [%s | %s | %s | %s | " ZBX_FS_DBL "%s %s%s%s%s]",
					s->s_name, e_string, s_type_string, s_reading_type_string,
					val, percent, base, mod_use, modifier, rate);
			break;
	}
	h->done = 1;
}
Ejemplo n.º 6
0
static void
got_thresh_reading(ipmi_sensor_t             *sensor,
		   int                       err,
		   enum ipmi_value_present_e value_present,
		   unsigned int              raw_value,
		   double                    val,
		   ipmi_states_t             *states,
		   void                      *cb_data)
{
    sdata_t            *sdata = cb_data;
    enum ipmi_thresh_e thresh;

    if (err) {
	printf("Error 0x%x getting discrete states for sensor %s\n",
	       err, sdata->name);
	goto out;
    }

    printf("Got threshold reading for sensor %s\n", sdata->name);
    if (ipmi_is_event_messages_enabled(states))
	printf("  event messages enabled\n");
    if (ipmi_is_sensor_scanning_enabled(states))
	printf("  sensor scanning enabled\n");
    if (ipmi_is_initial_update_in_progress(states))
	printf("  initial update in progress\n");

    switch (value_present)
    {
    case IPMI_NO_VALUES_PRESENT:
	printf("  no value present\n");
	break;
    case IPMI_BOTH_VALUES_PRESENT:
	{
	    const char *percent = "";
	    const char *base;
	    const char *mod_use = "";
	    const char *modifier = "";
	    const char *rate;

	    base = ipmi_sensor_get_base_unit_string(sensor);
	    if (ipmi_sensor_get_percentage(sensor))
		percent = "%";
	    switch (ipmi_sensor_get_modifier_unit_use(sensor)) {
	    case IPMI_MODIFIER_UNIT_NONE:
		break;
	    case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
		mod_use = "/";
		modifier = ipmi_sensor_get_modifier_unit_string(sensor);
		break;
	    case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
		mod_use = "*";
		modifier = ipmi_sensor_get_modifier_unit_string(sensor);
		break;
	    }
	    rate = ipmi_sensor_get_rate_unit_string(sensor);
	    
	    printf("  value: %lf%s %s%s%s%s\n", val, percent,
		   base, mod_use, modifier, rate);
	}
	/* FALLTHROUGH */
    case IPMI_RAW_VALUE_PRESENT:
	printf("  raw value: 0x%2.2x\n", raw_value);
    }

    if (sdata->thresh_sup == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
	goto out;

    for (thresh=IPMI_LOWER_NON_CRITICAL;
	 thresh<=IPMI_UPPER_NON_RECOVERABLE;
	 thresh++)
    {
	int val, rv;

	rv = ipmi_sensor_threshold_reading_supported(sensor, thresh, &val);
	if (rv || !val)
	    continue;

	if (ipmi_is_threshold_out_of_range(states, thresh))
	    printf("  Threshold %s is out of range\n",
		   ipmi_get_threshold_string(thresh));
	else
	    printf("  Threshold %s is in range\n",
		   ipmi_get_threshold_string(thresh));
    }

 out:
    release_sdata(sdata);
}