Hardware/ATI/ADL.cs
author moel.mich
Sat, 31 Dec 2011 17:31:04 +0000
changeset 324 c6ee430d6995
parent 200 50de2faf3336
child 333 c34cbcc7df66
permissions -rw-r--r--
Modified and extended version of the patch v4 by Roland Reinl (see Issue 256). Main differences to the original patch: DeviceIoControl refactorings removed, SmartAttribute is now descriptive only and does not hold any state, report is written as one 80 columns table, sensors are created only for meaningful values and without duplicates (remaining life, temperatures, host writes and reads). Also the current implementation should really preserve all the functionality of the old system. Additionally there is now a simple SMART devices emulation class (DebugSmart) that can be used in place of WindowsSmart for testing with reported data.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Runtime.InteropServices;
moel@1
    40
moel@1
    41
namespace OpenHardwareMonitor.Hardware.ATI {
moel@1
    42
  
moel@1
    43
  [StructLayout(LayoutKind.Sequential)]
moel@165
    44
  internal struct ADLAdapterInfo {
moel@1
    45
    public int Size;
moel@1
    46
    public int AdapterIndex;
moel@1
    47
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    48
    public string UDID;
moel@1
    49
    public int BusNumber;
moel@3
    50
    public int DeviceNumber;
moel@1
    51
    public int FunctionNumber;
moel@1
    52
    public int VendorID;
moel@1
    53
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    54
    public string AdapterName;
moel@1
    55
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    56
    public string DisplayName;
moel@1
    57
    public int Present;
moel@1
    58
    public int Exist;
moel@1
    59
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    60
    public string DriverPath;
moel@1
    61
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    62
    public string DriverPathExt;
moel@1
    63
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    64
    public string PNPString;
moel@1
    65
    public int OSDisplayIndex;
moel@1
    66
  }
moel@1
    67
moel@1
    68
  [StructLayout(LayoutKind.Sequential)]
moel@165
    69
  internal struct ADLPMActivity {
moel@1
    70
    public int Size;
moel@1
    71
    public int EngineClock;
moel@1
    72
    public int MemoryClock;
moel@1
    73
    public int Vddc;
moel@1
    74
    public int ActivityPercent;
moel@1
    75
    public int CurrentPerformanceLevel;
moel@1
    76
    public int CurrentBusSpeed;
moel@1
    77
    public int CurrentBusLanes;
moel@1
    78
    public int MaximumBusLanes;
moel@1
    79
    public int Reserved;
moel@1
    80
  }
moel@1
    81
moel@1
    82
  [StructLayout(LayoutKind.Sequential)]
moel@165
    83
  internal struct ADLTemperature {
moel@1
    84
    public int Size;
moel@1
    85
    public int Temperature;
moel@1
    86
  }
moel@1
    87
moel@1
    88
  [StructLayout(LayoutKind.Sequential)]
moel@165
    89
  internal struct ADLFanSpeedValue {
moel@1
    90
    public int Size;
moel@1
    91
    public int SpeedType;
moel@1
    92
    public int FanSpeed;
moel@1
    93
    public int Flags;
moel@1
    94
  }
moel@1
    95
moel@1
    96
  [StructLayout(LayoutKind.Sequential)]
moel@165
    97
  internal struct ADLFanSpeedInfo {
moel@1
    98
    public int Size;
moel@1
    99
    public int Flags;
moel@1
   100
    public int MinPercent;
moel@1
   101
    public int MaxPercent;
moel@1
   102
    public int MinRPM;
moel@1
   103
    public int MaxRPM;
moel@1
   104
  }
moel@1
   105
moel@165
   106
  internal class ADL {
moel@1
   107
    public const int ADL_MAX_PATH = 256;
moel@1
   108
    public const int ADL_MAX_ADAPTERS = 40;
moel@1
   109
    public const int ADL_MAX_DISPLAYS = 40;
moel@1
   110
    public const int ADL_MAX_DEVICENAME = 32;
moel@6
   111
    public const int ADL_OK = 0;
moel@15
   112
    public const int ADL_ERR = -1;
moel@1
   113
    public const int ADL_DRIVER_OK = 0;
moel@1
   114
    public const int ADL_MAX_GLSYNC_PORTS = 8;
moel@1
   115
    public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
moel@1
   116
    public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
moel@1
   117
moel@1
   118
    public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
moel@1
   119
    public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
moel@1
   120
moel@1
   121
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
moel@1
   122
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
moel@1
   123
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
moel@1
   124
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
moel@247
   125
    public const int ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1;
moel@1
   126
moel@3
   127
    public const int ATI_VENDOR_ID1 = 1002;
moel@3
   128
    public const int ATI_VENDOR_ID2 = 0x1002;
moel@3
   129
moel@1
   130
    private delegate int ADL_Main_Control_CreateDelegate(
moel@1
   131
      ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
moel@1
   132
    private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
moel@1
   133
      int size);
moel@1
   134
moel@1
   135
    public delegate int ADL_Main_Control_DestroyDelegate();
moel@1
   136
    public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
moel@1
   137
      ref int numAdapters);    
moel@1
   138
    public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
moel@1
   139
      out int adapterID);
moel@12
   140
    public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
moel@12
   141
      out int adapterID);      	
moel@1
   142
    public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
moel@1
   143
      out int status);
moel@1
   144
    public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
moel@1
   145
      int iAdapterIndex, ref ADLPMActivity activity);
moel@1
   146
    public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
moel@1
   147
        int thermalControllerIndex, ref ADLTemperature temperature);
moel@1
   148
    public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
moel@1
   149
        int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
moel@1
   150
    public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
moel@1
   151
      int adapterIndex, int thermalControllerIndex,
moel@1
   152
      ref ADLFanSpeedInfo fanSpeedInfo);
moel@247
   153
    public delegate int ADL_Overdrive5_FanSpeedToDefault_SetDelegate(
moel@247
   154
      int adapterIndex, int thermalControllerIndex);
moel@247
   155
    public delegate int ADL_Overdrive5_FanSpeed_SetDelegate(int adapterIndex,
moel@247
   156
      int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
moel@1
   157
moel@1
   158
    private static ADL_Main_Control_CreateDelegate
moel@1
   159
      _ADL_Main_Control_Create;
moel@1
   160
    private static ADL_Adapter_AdapterInfo_GetDelegate
moel@1
   161
      _ADL_Adapter_AdapterInfo_Get;
moel@1
   162
moel@167
   163
    public static ADL_Main_Control_DestroyDelegate
moel@1
   164
      ADL_Main_Control_Destroy;
moel@1
   165
    public static ADL_Adapter_NumberOfAdapters_GetDelegate
moel@1
   166
      ADL_Adapter_NumberOfAdapters_Get;
moel@12
   167
    public static ADL_Adapter_ID_GetDelegate 
moel@12
   168
      _ADL_Adapter_ID_Get;
moel@12
   169
    public static ADL_Display_AdapterID_GetDelegate 
moel@12
   170
      _ADL_Display_AdapterID_Get;
moel@12
   171
    public static ADL_Adapter_Active_GetDelegate 
moel@1
   172
      ADL_Adapter_Active_Get;
moel@1
   173
    public static ADL_Overdrive5_CurrentActivity_GetDelegate
moel@1
   174
      ADL_Overdrive5_CurrentActivity_Get;
moel@1
   175
    public static ADL_Overdrive5_Temperature_GetDelegate
moel@1
   176
      ADL_Overdrive5_Temperature_Get;
moel@1
   177
    public static ADL_Overdrive5_FanSpeed_GetDelegate
moel@1
   178
      ADL_Overdrive5_FanSpeed_Get;
moel@1
   179
    public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
moel@1
   180
      ADL_Overdrive5_FanSpeedInfo_Get;
moel@247
   181
    public static ADL_Overdrive5_FanSpeedToDefault_SetDelegate
moel@247
   182
      ADL_Overdrive5_FanSpeedToDefault_Set;
moel@247
   183
    public static ADL_Overdrive5_FanSpeed_SetDelegate
moel@247
   184
      ADL_Overdrive5_FanSpeed_Set;
moel@1
   185
moel@8
   186
    private static string dllName;
moel@1
   187
moel@1
   188
    private static void GetDelegate<T>(string entryPoint, out T newDelegate)
moel@1
   189
      where T : class 
moel@1
   190
    {
moel@8
   191
      DllImportAttribute attribute = new DllImportAttribute(dllName);
moel@1
   192
      attribute.CallingConvention = CallingConvention.StdCall;
moel@1
   193
      attribute.PreserveSig = true;
moel@1
   194
      attribute.EntryPoint = entryPoint;
moel@1
   195
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@1
   196
    }
moel@1
   197
moel@8
   198
    private static void CreateDelegates(string name) {
moel@195
   199
      int p = (int)Environment.OSVersion.Platform;
moel@8
   200
      if ((p == 4) || (p == 128))
moel@8
   201
        dllName = name + ".so";
moel@8
   202
      else
moel@8
   203
        dllName = name + ".dll";
moel@8
   204
moel@8
   205
      GetDelegate("ADL_Main_Control_Create",
moel@8
   206
        out _ADL_Main_Control_Create);
moel@8
   207
      GetDelegate("ADL_Adapter_AdapterInfo_Get",
moel@8
   208
        out _ADL_Adapter_AdapterInfo_Get);
moel@8
   209
      GetDelegate("ADL_Main_Control_Destroy",
moel@8
   210
        out ADL_Main_Control_Destroy);
moel@8
   211
      GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
moel@8
   212
        out ADL_Adapter_NumberOfAdapters_Get);
moel@8
   213
      GetDelegate("ADL_Adapter_ID_Get",
moel@12
   214
        out _ADL_Adapter_ID_Get);
moel@12
   215
      GetDelegate("ADL_Display_AdapterID_Get", 
moel@12
   216
        out _ADL_Display_AdapterID_Get);
moel@8
   217
      GetDelegate("ADL_Adapter_Active_Get",
moel@8
   218
        out ADL_Adapter_Active_Get);
moel@8
   219
      GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
moel@8
   220
        out ADL_Overdrive5_CurrentActivity_Get);
moel@8
   221
      GetDelegate("ADL_Overdrive5_Temperature_Get",
moel@8
   222
        out ADL_Overdrive5_Temperature_Get);
moel@8
   223
      GetDelegate("ADL_Overdrive5_FanSpeed_Get",
moel@8
   224
        out ADL_Overdrive5_FanSpeed_Get);
moel@8
   225
      GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
moel@8
   226
        out ADL_Overdrive5_FanSpeedInfo_Get);
moel@247
   227
      GetDelegate("ADL_Overdrive5_FanSpeedToDefault_Set",
moel@247
   228
        out ADL_Overdrive5_FanSpeedToDefault_Set);
moel@247
   229
      GetDelegate("ADL_Overdrive5_FanSpeed_Set",
moel@247
   230
        out ADL_Overdrive5_FanSpeed_Set);
moel@8
   231
    }
moel@8
   232
moel@1
   233
    static ADL() {
moel@8
   234
      CreateDelegates("atiadlxx");
moel@1
   235
    }
moel@1
   236
moel@1
   237
    private ADL() { }
moel@1
   238
moel@1
   239
    public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
moel@8
   240
      try {
moel@160
   241
        try {
moel@160
   242
          return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@160
   243
            enumConnectedAdapters);
moel@160
   244
        } catch {
moel@160
   245
          CreateDelegates("atiadlxy");
moel@160
   246
          return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@160
   247
            enumConnectedAdapters);
moel@160
   248
        }
moel@160
   249
      } catch {
moel@195
   250
        return ADL_ERR;
moel@8
   251
      }
moel@1
   252
    }
moel@1
   253
moel@1
   254
    public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
moel@1
   255
      int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
moel@1
   256
      int size = info.Length * elementSize;
moel@1
   257
      IntPtr ptr = Marshal.AllocHGlobal(size);
moel@1
   258
      int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
moel@1
   259
      for (int i = 0; i < info.Length; i++)
moel@1
   260
        info[i] = (ADLAdapterInfo)
moel@1
   261
          Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
moel@1
   262
          typeof(ADLAdapterInfo));
moel@1
   263
      Marshal.FreeHGlobal(ptr);
moel@1
   264
      return result;
moel@1
   265
    }
moel@1
   266
moel@12
   267
    public static int ADL_Adapter_ID_Get(int adapterIndex,
moel@12
   268
      out int adapterID) {
moel@12
   269
      try {
moel@12
   270
        return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
moel@12
   271
      } catch (EntryPointNotFoundException) {
moel@12
   272
        try {
moel@12
   273
          return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
moel@12
   274
        } catch (EntryPointNotFoundException) {
moel@12
   275
          adapterID = 1;
moel@12
   276
          return ADL_OK;
moel@12
   277
        }
moel@12
   278
      }
moel@12
   279
    }
moel@12
   280
moel@1
   281
    private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
moel@1
   282
moel@200
   283
    // create a Main_Memory_Alloc delegate and keep it alive
moel@200
   284
    private static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc =
moel@200
   285
      delegate(int size) {
moel@200
   286
        return Marshal.AllocHGlobal(size);
moel@200
   287
      };
moel@1
   288
moel@1
   289
    private static void Main_Memory_Free(IntPtr buffer) {
moel@1
   290
      if (IntPtr.Zero != buffer)
moel@1
   291
        Marshal.FreeHGlobal(buffer);
moel@1
   292
    }
moel@1
   293
  }
moel@1
   294
}