+++ /dev/null
-/*
- * Copyright (C) 2010-2011 thgreasi@gmail.com, jeanfi@gmail.com
- * Copyright (C) 2012-2014 jeanfi@gmail.com
- *
- * GPU usage is a contribution of MestreLion
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#ifndef LINUX
-#define LINUX 1
-#endif
-
-#include <locale.h>
-#include <libintl.h>
-#define _(str) gettext(str)
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <adl_sdk.h>
-
-#include <psensor.h>
-
-typedef int (*ADL_MAIN_CONTROL_CREATE)(ADL_MAIN_MALLOC_CALLBACK, int);
-typedef int (*ADL_MAIN_CONTROL_DESTROY)();
-typedef int (*ADL_ADAPTER_NUMBEROFADAPTERS_GET) (int *);
-typedef int (*ADL_ADAPTER_ADAPTERINFO_GET) (LPAdapterInfo, int);
-typedef int (*ADL_ADAPTER_ACTIVE_GET) (int, int*);
-typedef int (*ADL_OD5_TEMPERATURE_GET) (int, int, ADLTemperature*);
-typedef int (*ADL_OD5_FANSPEED_GET) (int, int, ADLFanSpeedValue*);
-typedef int (*ADL_OD5_CURRENTACTIVITY_GET) (int, ADLPMActivity*);
-
-static ADL_MAIN_CONTROL_CREATE adl_main_control_create;
-static ADL_MAIN_CONTROL_DESTROY adl_main_control_destroy;
-static ADL_ADAPTER_NUMBEROFADAPTERS_GET adl_adapter_numberofadapters_get;
-static ADL_ADAPTER_ADAPTERINFO_GET adl_adapter_adapterinfo_get;
-static ADL_ADAPTER_ACTIVE_GET adl_adapter_active_get;
-static ADL_OD5_TEMPERATURE_GET adl_od5_temperature_get;
-static ADL_OD5_FANSPEED_GET adl_od5_fanspeed_get;
-static ADL_OD5_CURRENTACTIVITY_GET adl_od5_currentactivity_get;
-
-static void *hdll;
-static int adl_main_control_done;
-static int *active_adapters;
-
-static void __stdcall *adl_main_memory_alloc(int isize)
-{
- void *lpbuffer = malloc(isize);
- return lpbuffer;
-}
-
-static void *getprocaddress(void *plibrary, const char *name)
-{
- return dlsym(plibrary, name);
-}
-
-/* Returns the temperature (Celsius) of an AMD/ATI GPU. */
-static double get_temp(struct psensor *sensor)
-{
- ADLTemperature v;
-
- v.iSize = sizeof(ADLTemperature);
- v.iTemperature = -273;
-
- if (ADL_OK == adl_od5_temperature_get(sensor->amd_id, 0, &v))
- return v.iTemperature/1000;
-
- return UNKNOWN_DBL_VALUE;
-}
-
-static double get_fanspeed(struct psensor *sensor)
-{
- ADLFanSpeedValue v;
-
- v.iSize = sizeof(ADLFanSpeedValue);
- v.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM;
- v.iFanSpeed = -1;
-
- if (ADL_OK == adl_od5_fanspeed_get(sensor->amd_id, 0, &v))
- return v.iFanSpeed;
-
- return UNKNOWN_DBL_VALUE;
-}
-
-static double get_usage(struct psensor *sensor)
-{
- ADLPMActivity v;
-
- v.iSize = sizeof(ADLPMActivity);
-
- if (ADL_OK == adl_od5_currentactivity_get(sensor->amd_id, &v))
- return v.iActivityPercent;
-
- return UNKNOWN_DBL_VALUE;
-}
-
-static struct psensor *create_sensor(int id, int type, int values_len)
-{
- char name[200];
- char *sid;
- int sensor_type;
- struct psensor *s;
-
- sensor_type = SENSOR_TYPE_ATIADL;
- switch (type) {
- /* Fan rotation speed */
- case 0:
- sprintf(name, "AMD GPU%d Fan", id);
- sensor_type |= SENSOR_TYPE_FAN | SENSOR_TYPE_RPM;
- break;
-
- /* Temperature */
- case 1:
- sprintf(name, "AMD GPU%d Temperature", id);
- sensor_type |= SENSOR_TYPE_GPU | SENSOR_TYPE_TEMP;
- break;
-
- /* GPU Usage (Activity/Load %) */
- case 2:
- sprintf(name, "AMD GPU%d Usage", id);
- sensor_type |= SENSOR_TYPE_GPU | SENSOR_TYPE_PERCENT;
- break;
- }
-
- sid = malloc(strlen("amd") + 1 + strlen(name) + 1);
- sprintf(sid, "amd %s", name);
-
- s = psensor_create(sid,
- strdup(name),
- strdup("AMD/ATI GPU"),
- sensor_type,
- values_len);
-
- s->amd_id = active_adapters[id];
-
- return s;
-}
-
-/*
- Returns the number of active AMD/ATI GPU adapters
-
- Return 0 if no AMD/ATI GPUs or cannot get information.
-*/
-static int init()
-{
- LPAdapterInfo lpadapterinfo;
- int i, inumberadapters, inumberadaptersactive, lpstatus, iadapterindex;
-
- adl_main_control_done = 0;
- inumberadaptersactive = 0;
- active_adapters = NULL;
- lpadapterinfo = NULL;
-
- hdll = dlopen("libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL);
- if (!hdll) {
- log_debug(_("AMD: cannot found ADL library."));
- return 0;
- }
-
- adl_main_control_create = (ADL_MAIN_CONTROL_CREATE)
- getprocaddress(hdll, "ADL_Main_Control_Create");
- adl_main_control_destroy = (ADL_MAIN_CONTROL_DESTROY)
- getprocaddress(hdll, "ADL_Main_Control_Destroy");
- adl_adapter_numberofadapters_get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET)
- getprocaddress(hdll, "ADL_Adapter_NumberOfAdapters_Get");
- adl_adapter_adapterinfo_get = (ADL_ADAPTER_ADAPTERINFO_GET)
- getprocaddress(hdll, "ADL_Adapter_AdapterInfo_Get");
- adl_adapter_active_get = (ADL_ADAPTER_ACTIVE_GET)
- getprocaddress(hdll, "ADL_Adapter_Active_Get");
- adl_od5_temperature_get = (ADL_OD5_TEMPERATURE_GET)
- getprocaddress(hdll, "ADL_Overdrive5_Temperature_Get");
- adl_od5_fanspeed_get = (ADL_OD5_FANSPEED_GET)
- getprocaddress(hdll, "ADL_Overdrive5_FanSpeed_Get");
- adl_od5_currentactivity_get = (ADL_OD5_CURRENTACTIVITY_GET)
- getprocaddress(hdll, "ADL_Overdrive5_CurrentActivity_Get");
- if (!adl_main_control_create
- || !adl_main_control_destroy
- || !adl_adapter_numberofadapters_get
- || !adl_adapter_adapterinfo_get
- || !adl_od5_temperature_get
- || !adl_od5_fanspeed_get
- || !adl_od5_currentactivity_get) {
- log_err(_("AMD: missing ADL's API."));
- return 0;
- }
-
- /*
- 1 in 2nd parameter means retrieve adapter information only
- for adapters that are physically present and enabled in the
- system
- */
- if (ADL_OK != adl_main_control_create(adl_main_memory_alloc, 1)) {
- log_err(_("AMD: failed to initialize ADL."));
- return 0;
- }
- adl_main_control_done = 1;
-
- if (ADL_OK != adl_adapter_numberofadapters_get(&inumberadapters)) {
- log_err(_("AMD: cannot get the number of adapters."));
- return 0;
- }
-
- if (!inumberadapters)
- return 0;
-
- lpadapterinfo = malloc(sizeof(AdapterInfo) * inumberadapters);
- memset(lpadapterinfo, '\0', sizeof(AdapterInfo) * inumberadapters);
-
- adl_adapter_adapterinfo_get(lpadapterinfo,
- sizeof(AdapterInfo) * inumberadapters);
-
- for (i = 0; i < inumberadapters; i++) {
-
- iadapterindex = lpadapterinfo[i].iAdapterIndex;
-
- if (ADL_OK != adl_adapter_active_get(iadapterindex, &lpstatus))
- continue;
- if (lpstatus != ADL_TRUE)
- continue;
-
- if (!active_adapters) {
- active_adapters = (int *) malloc(sizeof(int));
- inumberadaptersactive = 1;
- } else {
- ++inumberadaptersactive;
- active_adapters = (int *)realloc
- (active_adapters,
- sizeof(int)*inumberadaptersactive);
-
- if (!active_adapters)
- exit(EXIT_FAILURE);
- }
- active_adapters[inumberadaptersactive-1] = iadapterindex;
- }
-
- free(lpadapterinfo);
-
- log_debug(_("Number of AMD/ATI adapters: %d"), inumberadapters);
- log_debug(_("Number of active AMD/ATI adapters: %d"),
- inumberadaptersactive);
-
- return inumberadaptersactive;
-}
-
-/* Called regularly to update sensors values */
-void amd_psensor_list_update(struct psensor **sensors)
-{
- struct psensor **ss, *s;
-
- ss = sensors;
- while (*ss) {
- s = *ss;
-
- if (s->type & SENSOR_TYPE_ATIADL) {
- if (s->type & SENSOR_TYPE_TEMP)
- psensor_set_current_value(s, get_temp(s));
- else if (s->type & SENSOR_TYPE_RPM)
- psensor_set_current_value(s, get_fanspeed(s));
- else if (s->type & SENSOR_TYPE_PERCENT)
- psensor_set_current_value(s, get_usage(s));
- }
-
- ss++;
- }
-}
-
-/* Entry point for AMD sensors */
-void amd_psensor_list_append(struct psensor ***sensors, int values_len)
-{
- int i, j, n;
- struct psensor *s;
-
- n = init();
-
- for (i = 0; i < n; i++)
- /* Each GPU Adapter has 3 sensors: temp, fan speed and usage */
- for (j = 0; j < 3; j++) {
- s = create_sensor(i, j, values_len);
- psensor_list_append(sensors, s);
- }
-}
-
-void amd_cleanup()
-{
- if (hdll) {
- if (adl_main_control_done)
- adl_main_control_destroy();
- dlclose(hdll);
- }
-
- if (active_adapters) {
- free(active_adapters);
- active_adapters = NULL;
- }
-}