/**
* $Id: k10.c 488 2012-07-01 21:49:18Z elkner $
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in the appropriate
* files. If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2012 Jens Elkner. All rights reserved.
* Use is subject to license terms.
*/
/*
* AMD CPUs utilizing the k10sensor kernel driver's kstats.
*/
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <glib.h>
#include <gmodule.h>
#include <kstat.h>
#include <sysplugin.h>
#include <k10sensor_kstats.h>
#ifdef ENABLE_DTRACE
#include "probes.h"
#else
#define GKRELLM_STATS_DEBUG_ENABLED() (0)
#endif
/**
* Automatically called when the module gets loaded.
* @param module the GModule structure corresponding to this module.
* @return NULL on success, a string describing the initialization error
* otherwise.
*/
const gchar *
return ("kstat_open failed");
}
return ("kstat_chain_update failed");
}
return NULL;
}
/**
* Automatically called when the modul gets unloaded.
* Use it to free any resources aquired by this addon.
* @param module the GModule structure corresponding to this module.
*/
void
}
if (info_table != NULL) {
info_table = NULL;
}
if (data_table != NULL) {
data_table = NULL;
}
if (diode_offsets != NULL) {
}
dev_count = -1;
data_per_dev = 1;
lastCID = -1;
}
/**
* Get the number of all accessible data sources of the given device type.
* and the addOn is able to read its current aka measured value.
* @return a number >= 0.
*/
return 0;
}
if (dev_count >= 0) {
return dev_count;
}
return 0;
}
if (GKRELLM_STATS_DEBUG_ENABLED()) {
}
continue;
}
{
}
}
} else {
}
/* 0 usually causes, that update() below gets never called */
return dev_count * data_per_dev;
}
static gboolean
checkKstats() {
perror("kstat_chain_update failed");
return FALSE;
}
return TRUE;
}
if (GKRELLM_STATS_DEBUG_ENABLED()) {
}
{
continue;
}
info_count--;
if (data_per_dev != 1) {
} else {
}
data_count--;
}
if (data_count == 0 && info_count == 0) {
break;
}
}
return TRUE;
}
/**
* Initialize the n-th data source of the given device type and return its basic
* parameters. The ID is given by the callee, all other parameters must be
* filled in by the module. The callee creates a copy of these values on
* reception and frees all strings, so keeping a reference to these fields is
* useless and later access may run into segfaults.
* <p>
* Per contract this function gets never called as long as #getCount(DeviceType)
* returns 0.
*
* @param type The type aka category of device, the data source belongs to.
* @param id ID, which will be used by the callee to query value updates
* for the given data source. The ID is in the range of
* 0 .. #getCount(DeviceType)-1 wrt. the given device type.
* @param name The human readable name of the data source. Should be short
* (i.e. not longer than 40 characters) and sufficient to let a user
* identify the data source (so generic names are discouraged). Gets
* usually exposed to the UI as is. The string must be nul-terminated and
* might be truncated at the size of 128 chars by gkrellm.
* @param desc An optional, more detailed description of the data source.
* Use NULL if n/a. Might be exposed to the UI as tooltip or explicit text.
* The string must be nul-terminated.
* @param label The label for the sensor to be used. Usually an abbrev. of
* the <var>name</var>, which is displayed as a treenode in a GUI or chart.
* So it should not be longer than 10 characters. The string must be
* nul-terminated and might be truncated at the size of 64 chars by
* gkrellm.
* @param min The lower limit of the data source range.
* Use G_MININT32 if n/a.
* @param max The upper limit of the data source range.
* Use G_MAXINT32 if n/a.
* @param lowThreshold The low threshold a data source may have. E.g. wrt. to
* a temperature sensor an indicator when to start drinking whisky and wine.
* Use G_MININT32 if n/a.
* @param highThreshold The high threshold a data source may have. E.g. Nvidia
* GPUs have usually a high threshold (read-only), which determines when
* to slow down the GPU. Use G_MAXINT32 if n/a.
* @return TRUE on success (i.e. the callee can assume, that successive calls to
* #updateSource(DeviceType, int) can be done and return correct values.
*/
{
int tcrit;
/* for paranoid people */
return FALSE;
}
if (info_table == NULL) {
if (info_table == NULL) {
perror("k10 init: info table alloc");
return FALSE;
}
if (data_table == NULL) {
perror("k10 init: data table init");
return FALSE;
}
if (diode_offsets == NULL) {
perror("k10 init: offset table");
return FALSE;
}
}
if (!checkKstats()) {
return FALSE;
}
if (data_per_dev != 1) {
} else {
}
*desc = "Is not a phys. temperature, i.e. a value of 70 may point to 80°C";
*min = G_MININT32;
*max = G_MAXINT32;
return FALSE;
}
max -= 49000;
min -= 49000;
/* 0Fh: HTC info inaccessible - use STC instead */
} else {
}
if (tcrit != G_MAXINT32) {
}
return TRUE;
}
/**
* Update the current value of the source with the given ID and type.
* <p>
* Per contract this function gets never called as long as #getCount(DeviceType)
* returns 0.
* @param type type of the device
* @param id the ID assigned by the callee (see #initSensor())
* @param value the field, where the current value should be stored
* @return TRUE if the update was successful.
*/
/* for paranoid people */
return FALSE;
}
if (!checkKstats()) {
return FALSE;
}
return FALSE;
}
if (*value == 0) {
return FALSE;
}
return TRUE;
}
#ifndef PIC
int
if (g_module_check_init(NULL)) {
exit(1);
}
if (data == 0) {
printf("No temperature data for AMD CPUs available\n");
exit(0);
}
for (i=0; i < data; i++) {
} else {
}
} else {
printf("init for data %d failed\n", i);
}
}
exit(0);
}
#endif