Blame opae-libs/plugins/xfpga/metrics/bmc/bmc.c

Packit 534379
// Copyright(c) 2018-2020, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
#include "bmc.h"
Packit 534379
#define _TIMESPEC_DEFINED
Packit 534379
#include "../../types_int.h"
Packit 534379
#include "bmcdata.h"
Packit 534379
#include <sys/types.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
#include <string.h>
Packit 534379
#ifndef _WIN32
Packit 534379
#include <unistd.h>
Packit 534379
#else
Packit 534379
#include <io.h>
Packit 534379
#endif
Packit 534379
#include <fcntl.h>
Packit 534379
#include <stdlib.h>
Packit 534379
Packit 534379
#include <glob.h>
Packit 534379
Packit 534379
#define NULL_CHECK(x)                                                          \
Packit 534379
	do {                                                                   \
Packit 534379
		if (NULL == (x)) {                                             \
Packit 534379
			return FPGA_INVALID_PARAM;                             \
Packit 534379
		}                                                              \
Packit 534379
	} while (0)
Packit 534379
Packit 534379
fpga_result read_sysfs_file(fpga_token token, const char *file,
Packit 534379
		   void **buf, uint32_t *tot_bytes_ret)
Packit 534379
{
Packit 534379
	char sysfspath[SYSFS_PATH_MAX] = { 0, };
Packit 534379
	struct stat stats;
Packit 534379
	int fd = 0;
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(token);
Packit 534379
	NULL_CHECK(buf);
Packit 534379
	NULL_CHECK(file);
Packit 534379
	NULL_CHECK(tot_bytes_ret);
Packit 534379
Packit 534379
	*buf = NULL;
Packit 534379
	*tot_bytes_ret = 0;
Packit 534379
Packit 534379
	struct _fpga_token *tok = (struct _fpga_token *)token;
Packit 534379
	if (FPGA_TOKEN_MAGIC != tok->magic) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (snprintf(sysfspath, sizeof(sysfspath),
Packit 534379
		     "%s/%s", tok->sysfspath, file) < 0) {
Packit 534379
		OPAE_ERR("snprintf buffer overflow");
Packit 534379
		return FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	glob_t pglob;
Packit 534379
	int gres = glob(sysfspath, GLOB_NOSORT, NULL, &pglob);
Packit 534379
	if ((gres) || (1 != pglob.gl_pathc)) {
Packit 534379
		globfree(&pglob);
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	fd = open(pglob.gl_pathv[0], O_RDONLY);
Packit 534379
	globfree(&pglob);
Packit 534379
	if (fd < 0) {
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	if (fstat(fd, &stats) != 0) {
Packit 534379
		close(fd);
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	// fstat for a sysfs file is not accurate for the BMC
Packit 534379
	// Read the entire file into a temp buffer to get actual size of file
Packit 534379
	*buf = (void *)calloc(stats.st_size, 1);
Packit 534379
Packit 534379
	int32_t tot_bytes = 0;
Packit 534379
	int32_t bytes_read = 0;
Packit 534379
	do {
Packit 534379
		bytes_read = (int32_t)read(fd, *buf, stats.st_size);
Packit 534379
		if (bytes_read < 0) {
Packit 534379
			if (errno == EINTR) {
Packit 534379
				bytes_read = 1; // Fool the while loop
Packit 534379
				continue;
Packit 534379
			}
Packit 534379
		}
Packit 534379
		tot_bytes += bytes_read;
Packit 534379
	} while ((tot_bytes < stats.st_size) && (bytes_read > 0));
Packit 534379
Packit 534379
	close(fd);
Packit 534379
Packit 534379
	if ((tot_bytes > stats.st_size) || (bytes_read < 0)) {
Packit 534379
		res = FPGA_EXCEPTION;
Packit 534379
		free(*buf);
Packit 534379
		*buf = NULL;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	*tot_bytes_ret = tot_bytes;
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcLoadSDRs(fpga_token token, bmc_sdr_handle *records,
Packit 534379
			uint32_t *num_sensors)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
	size_t len;
Packit 534379
Packit 534379
	NULL_CHECK(token);
Packit 534379
	NULL_CHECK(num_sensors);
Packit 534379
Packit 534379
	struct _sdr_rec *recs = NULL;
Packit 534379
Packit 534379
	struct _sdr_content *tmp = NULL;
Packit 534379
	uint32_t tot_bytes;
Packit 534379
Packit 534379
	res = read_sysfs_file(token, SYSFS_SDR_FILE, (void **)&tmp, &tot_bytes);
Packit 534379
	if (FPGA_OK != res) {
Packit 534379
		if (tmp) {
Packit 534379
			free(tmp);
Packit 534379
		}
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	uint32_t sz = sizeof(sdr_header) + sizeof(sdr_key) + sizeof(sdr_body);
Packit 534379
	uint32_t num_of_sensors = (tot_bytes + sz - 1) / sz;
Packit 534379
Packit 534379
	*num_sensors = num_of_sensors;
Packit 534379
	if (NULL == records) {
Packit 534379
		free(tmp);
Packit 534379
		return FPGA_OK;
Packit 534379
	}
Packit 534379
Packit 534379
	*records = (bmc_sdr_handle)calloc(1, sizeof(struct _sdr_rec));
Packit 534379
	if (NULL == *records) {
Packit 534379
		free(tmp);
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
	recs = (struct _sdr_rec *)*records;
Packit 534379
Packit 534379
	recs->contents = tmp;
Packit 534379
Packit 534379
	recs->magic = BMC_SDR_MAGIC;
Packit 534379
	recs->num_records = num_of_sensors;
Packit 534379
Packit 534379
	struct _fpga_token *tok = (struct _fpga_token *)token;
Packit 534379
Packit 534379
	len = strnlen(tok->sysfspath, SYSFS_PATH_MAX - 1);
Packit 534379
	strncpy(recs->sysfs_path, tok->sysfspath, len + 1);
Packit 534379
	recs->token = token;
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcReadSensorValues(bmc_sdr_handle records, bmc_values_handle *values,
Packit 534379
				uint32_t *num_values)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
	struct _bmc_values *vals = NULL;
Packit 534379
Packit 534379
	NULL_CHECK(records);
Packit 534379
	struct _sdr_rec *sdr = (struct _sdr_rec *)records;
Packit 534379
	struct _sensor_reading *tmp = NULL;
Packit 534379
Packit 534379
	if (BMC_SDR_MAGIC != sdr->magic) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	NULL_CHECK(num_values);
Packit 534379
Packit 534379
	if (NULL == values) {
Packit 534379
		*num_values = sdr->num_records;
Packit 534379
		return FPGA_OK;
Packit 534379
	}
Packit 534379
Packit 534379
	uint32_t tot_bytes;
Packit 534379
Packit 534379
	res = read_sysfs_file(sdr->token, SYSFS_SENSOR_FILE, (void **)&tmp,
Packit 534379
			      &tot_bytes);
Packit 534379
	if ((NULL == tmp) || (FPGA_OK != res)) {
Packit 534379
		fprintf(stderr, "Cannot read sensor file.\n");
Packit 534379
		if (tmp) {
Packit 534379
			free(tmp);
Packit 534379
		}
Packit 534379
		return FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tot_bytes != (sdr->num_records * sizeof(sensor_reading))) {
Packit 534379
		fprintf(stderr,
Packit 534379
			"Struct / file size mismatch: file size %d,"
Packit 534379
			" struct size %d.\n",
Packit 534379
			(int)tot_bytes,
Packit 534379
			(int)(sdr->num_records * sizeof(sensor_reading)));
Packit 534379
		free(tmp);
Packit 534379
		return FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	*num_values = sdr->num_records;
Packit 534379
Packit 534379
	*values = (bmc_values_handle)calloc(1, sizeof(struct _bmc_values));
Packit 534379
	if (NULL == *values) {
Packit 534379
		free(tmp);
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
	vals = (struct _bmc_values *)*values;
Packit 534379
Packit 534379
	vals->contents = tmp;
Packit 534379
Packit 534379
	vals->magic = BMC_VALUES_MAGIC;
Packit 534379
	vals->num_records = sdr->num_records;
Packit 534379
Packit 534379
	vals->values = (Values **)calloc(sdr->num_records, sizeof(Values *));
Packit 534379
	if (NULL == vals->values) {
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
Packit 534379
	uint32_t i;
Packit 534379
	for (i = 0; i < sdr->num_records; i++) {
Packit 534379
		vals->values[i] = bmc_build_values(
Packit 534379
			&vals->contents[i], &sdr->contents[i].header,
Packit 534379
			&sdr->contents[i].key, &sdr->contents[i].body);
Packit 534379
		vals->values[i]->sdr = &sdr->contents[i];
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcGetSensorReading(bmc_values_handle values,
Packit 534379
				uint32_t sensor_number, uint32_t *is_valid,
Packit 534379
				double *value)
Packit 534379
{
Packit 534379
	NULL_CHECK(values);
Packit 534379
	NULL_CHECK(value);
Packit 534379
	struct _bmc_values *vals = (struct _bmc_values *)values;
Packit 534379
Packit 534379
	if (BMC_VALUES_MAGIC != vals->magic) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (sensor_number >= vals->num_records) {
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	*is_valid = vals->values[sensor_number]->is_valid;
Packit 534379
Packit 534379
	*value = vals->values[sensor_number]->value.f_val;
Packit 534379
Packit 534379
	return FPGA_OK;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcThresholdsTripped(bmc_values_handle values,
Packit 534379
				 tripped_thresholds **tripped,
Packit 534379
				 uint32_t *num_tripped)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
	int num_tripd = 0;
Packit 534379
Packit 534379
	NULL_CHECK(values);
Packit 534379
	NULL_CHECK(num_tripped);
Packit 534379
Packit 534379
	struct _bmc_values *vals = (struct _bmc_values *)values;
Packit 534379
	uint32_t i;
Packit 534379
Packit 534379
	if (BMC_VALUES_MAGIC != vals->magic) {
Packit 534379
		res = FPGA_INVALID_PARAM;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	// Count the number tripped
Packit 534379
	for (i = 0; i < vals->num_records; i++) {
Packit 534379
		uint8_t indicators = vals->contents[i].threshold_events._value
Packit 534379
				     & BMC_THRESHOLD_EVENT_MASK;
Packit 534379
Packit 534379
		if (0 == indicators) {
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		num_tripd++;
Packit 534379
	}
Packit 534379
Packit 534379
	*num_tripped = num_tripd;
Packit 534379
	if (0 == num_tripd) {
Packit 534379
		if (NULL != tripped) {
Packit 534379
			*tripped = NULL;
Packit 534379
		}
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	*tripped = (tripped_thresholds *)calloc(num_tripd,
Packit 534379
						sizeof(tripped_thresholds));
Packit 534379
	if (NULL == *tripped) {
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
	tripped_thresholds *rets = *tripped;
Packit 534379
	int index = 0;
Packit 534379
Packit 534379
	// Fill in the tripped structures
Packit 534379
	for (i = 0; i < vals->num_records; i++) {
Packit 534379
		struct _sdr_content *sdr = vals->values[i]->sdr;
Packit 534379
		uint8_t indicators = vals->contents[i].threshold_events._value
Packit 534379
				     & BMC_THRESHOLD_EVENT_MASK;
Packit 534379
Packit 534379
		if (0 == indicators) {
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		rets[index].sensor_number = i;
Packit 534379
		rets[index].sensor_type = SDR_SENSOR_IS_POWER(&sdr->body)
Packit 534379
			? BMC_POWER : BMC_THERMAL;
Packit 534379
		rets[index].which_thresholds = indicators;
Packit 534379
		index++;
Packit 534379
	}
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcDestroySDRs(bmc_sdr_handle *records)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(records);
Packit 534379
	struct _sdr_rec *sdr = (struct _sdr_rec *)*records;
Packit 534379
Packit 534379
	if (BMC_SDR_MAGIC != sdr->magic) {
Packit 534379
		res = FPGA_INVALID_PARAM;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	free(sdr->contents);
Packit 534379
Packit 534379
	sdr->magic = 0;
Packit 534379
	free(sdr);
Packit 534379
Packit 534379
	*records = NULL;
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcDestroySensorValues(bmc_values_handle *values)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(values);
Packit 534379
	NULL_CHECK(*values);
Packit 534379
	struct _bmc_values *vals = (struct _bmc_values *)*values;
Packit 534379
	uint32_t i;
Packit 534379
Packit 534379
	if (BMC_VALUES_MAGIC != vals->magic) {
Packit 534379
		res = FPGA_INVALID_PARAM;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < vals->num_records; i++) {
Packit 534379
		free(vals->values[i]->name);
Packit 534379
		free(vals->values[i]);
Packit 534379
	}
Packit 534379
Packit 534379
	free(vals->contents);
Packit 534379
	free(vals->values);
Packit 534379
Packit 534379
	vals->magic = 0;
Packit 534379
	free(vals);
Packit 534379
Packit 534379
	*values = NULL;
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
static void getThresholdValues(sdr_details *details, Values *this_val,
Packit 534379
			       struct _sdr_content *sdr)
Packit 534379
{
Packit 534379
	uint8_t settable =
Packit 534379
		(sdr->body.discrete_settable_readable_threshold_mask._value
Packit 534379
		 & 0x3f00)
Packit 534379
		>> 8;
Packit 534379
Packit 534379
	details->thresholds.upper_nr_thresh.is_valid = 0;
Packit 534379
	details->thresholds.upper_c_thresh.is_valid = 0;
Packit 534379
	details->thresholds.upper_nc_thresh.is_valid = 0;
Packit 534379
	details->thresholds.lower_nr_thresh.is_valid = 0;
Packit 534379
	details->thresholds.lower_c_thresh.is_valid = 0;
Packit 534379
	details->thresholds.lower_nc_thresh.is_valid = 0;
Packit 534379
Packit 534379
	if (!settable) {
Packit 534379
		return;
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 5)) {
Packit 534379
		details->thresholds.upper_nr_thresh.is_valid = 1;
Packit 534379
		details->thresholds.upper_nr_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.upper_nr_threshold);
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 4)) {
Packit 534379
		details->thresholds.upper_c_thresh.is_valid = 1;
Packit 534379
		details->thresholds.upper_c_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.upper_c_threshold);
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 3)) {
Packit 534379
		details->thresholds.upper_nc_thresh.is_valid = 1;
Packit 534379
		details->thresholds.upper_nc_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.upper_nc_threshold);
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 2)) {
Packit 534379
		details->thresholds.lower_nr_thresh.is_valid = 1;
Packit 534379
		details->thresholds.lower_nr_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.lower_nr_threshold);
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 1)) {
Packit 534379
		details->thresholds.lower_c_thresh.is_valid = 1;
Packit 534379
		details->thresholds.lower_c_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.lower_c_threshold);
Packit 534379
	}
Packit 534379
Packit 534379
	if (settable & (1 << 0)) {
Packit 534379
		details->thresholds.lower_nc_thresh.is_valid = 1;
Packit 534379
		details->thresholds.lower_nc_thresh.value =
Packit 534379
			getvalue(this_val, sdr->body.lower_nc_threshold);
Packit 534379
	}
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcGetSDRDetails(bmc_values_handle values, uint32_t sensor_number,
Packit 534379
			     sdr_details *details)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(values);
Packit 534379
	NULL_CHECK(details);
Packit 534379
	struct _bmc_values *vals = (struct _bmc_values *)values;
Packit 534379
	Values *this_val = NULL;
Packit 534379
Packit 534379
	if (BMC_VALUES_MAGIC != vals->magic) {
Packit 534379
		res = FPGA_INVALID_PARAM;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (sensor_number >= vals->num_records) {
Packit 534379
		res = FPGA_INVALID_PARAM;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	this_val = vals->values[sensor_number];
Packit 534379
Packit 534379
	details->sensor_number = sensor_number;
Packit 534379
	details->sensor_type = this_val->sensor_type;
Packit 534379
	details->name = this_val->name;
Packit 534379
	details->units = this_val->units;
Packit 534379
	details->M = this_val->M;
Packit 534379
	details->B = this_val->B;
Packit 534379
	details->accuracy = this_val->accuracy;
Packit 534379
	details->tolerance = this_val->tolerance;
Packit 534379
	details->result_exp = this_val->result_exp;
Packit 534379
Packit 534379
	getThresholdValues(details, this_val, vals->values[sensor_number]->sdr);
Packit 534379
Packit 534379
out:
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcDestroyTripped(tripped_thresholds *tripped)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(tripped);
Packit 534379
Packit 534379
	free(tripped);
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcGetFirmwareVersion(fpga_token token, uint32_t *version)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(token);
Packit 534379
	NULL_CHECK(version);
Packit 534379
	*version = (uint32_t)-1;
Packit 534379
Packit 534379
	device_id *tmp = NULL;
Packit 534379
	uint32_t tot_bytes;
Packit 534379
Packit 534379
	res = read_sysfs_file(token, SYSFS_DEVID_FILE, (void **)&tmp,
Packit 534379
			      &tot_bytes);
Packit 534379
	if (FPGA_OK != res) {
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (!tmp) {
Packit 534379
		res = FPGA_EXCEPTION;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->completion_code != 0) {
Packit 534379
		res = FPGA_NOT_FOUND;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	*version = tmp->aux_fw_rev_0_7 | (tmp->aux_fw_rev_8_15 << 8)
Packit 534379
		   | (tmp->aux_fw_rev_16_23 << 16)
Packit 534379
		   | (tmp->aux_fw_rev_24_31 << 24);
Packit 534379
Packit 534379
out:
Packit 534379
	if (tmp) {
Packit 534379
		free(tmp);
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcGetLastPowerdownCause(fpga_token token, char **cause)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(token);
Packit 534379
	NULL_CHECK(cause);
Packit 534379
	*cause = NULL;
Packit 534379
Packit 534379
	powerdown_cause *tmp = NULL;
Packit 534379
	uint32_t tot_bytes;
Packit 534379
Packit 534379
	res = read_sysfs_file(token, SYSFS_PWRDN_FILE, (void **)&tmp,
Packit 534379
			      &tot_bytes);
Packit 534379
	if (FPGA_OK != res) {
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (!tmp) {
Packit 534379
		res = FPGA_EXCEPTION;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->completion_code != 0) {
Packit 534379
		res = FPGA_NOT_FOUND;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	*cause = strndup((const char *)tmp->message,
Packit 534379
		strnlen((const char *)tmp->message, SYSFS_PATH_MAX));
Packit 534379
Packit 534379
out:
Packit 534379
	if (tmp) {
Packit 534379
		free(tmp);
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result bmcGetLastResetCause(fpga_token token, char **cause)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
Packit 534379
	NULL_CHECK(token);
Packit 534379
	NULL_CHECK(cause);
Packit 534379
	*cause = NULL;
Packit 534379
Packit 534379
	reset_cause *tmp = NULL;
Packit 534379
	uint32_t tot_bytes;
Packit 534379
Packit 534379
	res = read_sysfs_file(token, SYSFS_RESET_FILE, (void **)&tmp,
Packit 534379
			      &tot_bytes);
Packit 534379
	if (FPGA_OK != res) {
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (!tmp) {
Packit 534379
		res = FPGA_EXCEPTION;
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->completion_code != 0) {
Packit 534379
		res = FPGA_NOT_FOUND;
Packit 534379
		*cause = strndup((const char *)"Unavailable",
Packit 534379
			strnlen((const char *)"Unavailable", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (0 == tmp->reset_cause) {
Packit 534379
		*cause = strndup((const char *)"None",
Packit 534379
			strnlen((const char *)"None", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_EXTRST) {
Packit 534379
		*cause = strndup((const char *)"External reset",
Packit 534379
			strnlen((const char *)"External reset", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_BOD_IO) {
Packit 534379
		*cause = strndup((const char *)"Brown-out detected",
Packit 534379
			strnlen((const char *)"Brown-out detected", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_OCD) {
Packit 534379
		*cause = strndup((const char *)"On-chip debug system",
Packit 534379
			strnlen((const char *)"On-chip debug system", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_POR) {
Packit 534379
		*cause = strndup((const char *)"Power-on-reset",
Packit 534379
			strnlen((const char *)"Power-on-reset", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_SOFT) {
Packit 534379
		*cause = strndup((const char *)"Software reset",
Packit 534379
			strnlen((const char *)"Software reset", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_SPIKE) {
Packit 534379
		*cause = strndup((const char *)"Spike detected",
Packit 534379
			strnlen((const char *)"Spike detected", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	if (tmp->reset_cause & CHIP_RESET_CAUSE_WDT) {
Packit 534379
		*cause = strndup((const char *)"Watchdog timeout",
Packit 534379
			strnlen((const char *)"Watchdog timeout", SYSFS_PATH_MAX));
Packit 534379
		goto out;
Packit 534379
	}
Packit 534379
Packit 534379
	*cause = strndup((const char *)"Unknown",
Packit 534379
		strnlen((const char *)"Unknown", SYSFS_PATH_MAX));
Packit 534379
Packit 534379
out:
Packit 534379
	if (tmp) {
Packit 534379
		free(tmp);
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}