Fixes for modern macos

This commit is contained in:
elvis
2025-11-04 20:50:54 +01:00
parent e1bd672bcd
commit ad77a7b2e8
2 changed files with 328 additions and 332 deletions

View File

@ -1,5 +1,5 @@
CC = gcc CC = clang
CFLAGS = -mmacosx-version-min=10.4 -Wall -g -framework IOKit CFLAGS = -Wall -g -framework IOKit
CPPFLAGS = -DCMD_TOOL_BUILD CPPFLAGS = -DCMD_TOOL_BUILD
all: smc all: smc
@ -11,4 +11,4 @@ smc.o: smc.h smc.c
$(CC) $(CPPFLAGS) -c smc.c $(CC) $(CPPFLAGS) -c smc.c
clean: clean:
-rm -f smc smc.o @-rm -f smc smc.o

View File

@ -25,6 +25,7 @@
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include "smc.h" #include "smc.h"
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#include <os/lock.h>
// Cache the keyInfo to lower the energy impact of SMCReadKey() / SMCReadKey2() // Cache the keyInfo to lower the energy impact of SMCReadKey() / SMCReadKey2()
#define KEY_INFO_CACHE_SIZE 100 #define KEY_INFO_CACHE_SIZE 100
@ -34,7 +35,7 @@ struct {
} g_keyInfoCache[KEY_INFO_CACHE_SIZE]; } g_keyInfoCache[KEY_INFO_CACHE_SIZE];
int g_keyInfoCacheCount = 0; int g_keyInfoCacheCount = 0;
OSSpinLock g_keyInfoSpinLock = 0; os_unfair_lock g_keyInfoSpinLock = OS_UNFAIR_LOCK_INIT;
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure, io_connect_t conn); kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure, io_connect_t conn);
@ -47,10 +48,10 @@ UInt32 _strtoul(char *str, int size, int base)
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
if (base == 16) if (base == 16)
total += str[i] << (size - 1 - i) * 8; total += str[i] << (size - 1 - i) * 8;
else else
total += ((unsigned char) (str[i]) << (size - 1 - i) * 8); total += ((unsigned char) (str[i]) << (size - 1 - i) * 8);
} }
return total; return total;
} }
@ -59,27 +60,27 @@ void _ultostr(char *str, UInt32 val)
{ {
str[0] = '\0'; str[0] = '\0';
sprintf(str, "%c%c%c%c", sprintf(str, "%c%c%c%c",
(unsigned int) val >> 24, (unsigned int) val >> 24,
(unsigned int) val >> 16, (unsigned int) val >> 16,
(unsigned int) val >> 8, (unsigned int) val >> 8,
(unsigned int) val); (unsigned int) val);
} }
float _strtof(unsigned char *str, int size, int e) float _strtof(unsigned char *str, int size, int e)
{ {
float total = 0; float total = 0;
int i; int i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
if (i == (size - 1)) if (i == (size - 1))
total += (str[i] & 0xff) >> e; total += (str[i] & 0xff) >> e;
else else
total += str[i] << (size - 1 - i) * (8 - e); total += str[i] << (size - 1 - i) * (8 - e);
} }
total += (str[size-1] & 0x03) * 0.25; total += (str[size-1] & 0x03) * 0.25;
return total; return total;
} }
@ -212,7 +213,7 @@ void printBytesHex(SMCVal_t val)
printf("(bytes"); printf("(bytes");
for (i = 0; i < val.dataSize; i++) for (i = 0; i < val.dataSize; i++)
printf(" %02x", (unsigned char) val.bytes[i]); printf(" %02x", (unsigned char) val.bytes[i]);
printf(")\n"); printf(")\n");
} }
@ -221,64 +222,62 @@ void printVal(SMCVal_t val)
printf(" %-4s [%-4s] ", val.key, val.dataType); printf(" %-4s [%-4s] ", val.key, val.dataType);
if (val.dataSize > 0) if (val.dataSize > 0)
{ {
if ((strcmp(val.dataType, DATATYPE_UINT8) == 0) || if ((strcmp(val.dataType, DATATYPE_UINT8) == 0) ||
(strcmp(val.dataType, DATATYPE_UINT16) == 0) || (strcmp(val.dataType, DATATYPE_UINT16) == 0) ||
(strcmp(val.dataType, DATATYPE_UINT32) == 0)) (strcmp(val.dataType, DATATYPE_UINT32) == 0))
printUInt(val); printUInt(val);
else if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4) else if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4)
printFLT(val); printFLT(val);
else if (strcmp(val.dataType, DATATYPE_FP1F) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP1F) == 0 && val.dataSize == 2)
printFP1F(val); printFP1F(val);
else if (strcmp(val.dataType, DATATYPE_FP4C) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP4C) == 0 && val.dataSize == 2)
printFP4C(val); printFP4C(val);
else if (strcmp(val.dataType, DATATYPE_FP5B) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP5B) == 0 && val.dataSize == 2)
printFP5B(val); printFP5B(val);
else if (strcmp(val.dataType, DATATYPE_FP6A) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP6A) == 0 && val.dataSize == 2)
printFP6A(val); printFP6A(val);
else if (strcmp(val.dataType, DATATYPE_FP79) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP79) == 0 && val.dataSize == 2)
printFP79(val); printFP79(val);
else if (strcmp(val.dataType, DATATYPE_FP88) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FP88) == 0 && val.dataSize == 2)
printFP88(val); printFP88(val);
else if (strcmp(val.dataType, DATATYPE_FPA6) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FPA6) == 0 && val.dataSize == 2)
printFPA6(val); printFPA6(val);
else if (strcmp(val.dataType, DATATYPE_FPC4) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FPC4) == 0 && val.dataSize == 2)
printFPC4(val); printFPC4(val);
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2)
printFPE2(val); printFPE2(val);
else if (strcmp(val.dataType, DATATYPE_SP1E) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP1E) == 0 && val.dataSize == 2)
printSP1E(val); printSP1E(val);
else if (strcmp(val.dataType, DATATYPE_SP3C) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP3C) == 0 && val.dataSize == 2)
printSP3C(val); printSP3C(val);
else if (strcmp(val.dataType, DATATYPE_SP4B) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP4B) == 0 && val.dataSize == 2)
printSP4B(val); printSP4B(val);
else if (strcmp(val.dataType, DATATYPE_SP5A) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP5A) == 0 && val.dataSize == 2)
printSP5A(val); printSP5A(val);
else if (strcmp(val.dataType, DATATYPE_SP69) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP69) == 0 && val.dataSize == 2)
printSP69(val); printSP69(val);
else if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2)
printSP78(val); printSP78(val);
else if (strcmp(val.dataType, DATATYPE_SP87) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP87) == 0 && val.dataSize == 2)
printSP87(val); printSP87(val);
else if (strcmp(val.dataType, DATATYPE_SP96) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SP96) == 0 && val.dataSize == 2)
printSP96(val); printSP96(val);
else if (strcmp(val.dataType, DATATYPE_SPB4) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SPB4) == 0 && val.dataSize == 2)
printSPB4(val); printSPB4(val);
else if (strcmp(val.dataType, DATATYPE_SPF0) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SPF0) == 0 && val.dataSize == 2)
printSPF0(val); printSPF0(val);
else if (strcmp(val.dataType, DATATYPE_SI8) == 0 && val.dataSize == 1) else if (strcmp(val.dataType, DATATYPE_SI8) == 0 && val.dataSize == 1)
printSI8(val); printSI8(val);
else if (strcmp(val.dataType, DATATYPE_SI16) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_SI16) == 0 && val.dataSize == 2)
printSI16(val); printSI16(val);
else if (strcmp(val.dataType, DATATYPE_PWM) == 0 && val.dataSize == 2) else if (strcmp(val.dataType, DATATYPE_PWM) == 0 && val.dataSize == 2)
printPWM(val); printPWM(val);
else if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4) else if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4)
printFLT(val); printFLT(val);
printBytesHex(val); printBytesHex(val);
} } else {
else printf("no data\n");
{
printf("no data\n");
} }
} }
@ -290,33 +289,33 @@ kern_return_t SMCOpen(io_connect_t *conn)
mach_port_t masterPort; mach_port_t masterPort;
io_iterator_t iterator; io_iterator_t iterator;
io_object_t device; io_object_t device;
IOMasterPort(MACH_PORT_NULL, &masterPort); IOMainPort(MACH_PORT_NULL, &masterPort);
CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC"); CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC");
result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
{ {
printf("Error: IOServiceGetMatchingServices() = %08x\n", result); printf("Error: IOServiceGetMatchingServices() = %08x\n", result);
return 1; return 1;
} }
device = IOIteratorNext(iterator); device = IOIteratorNext(iterator);
IOObjectRelease(iterator); IOObjectRelease(iterator);
if (device == 0) if (device == 0)
{ {
printf("Error: no SMC found\n"); printf("Error: no SMC found\n");
return 1; return 1;
} }
result = IOServiceOpen(device, mach_task_self(), 0, conn); result = IOServiceOpen(device, mach_task_self(), 0, conn);
IOObjectRelease(device); IOObjectRelease(device);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
{ {
printf("Error: IOServiceOpen() = %08x\n", result); printf("Error: IOServiceOpen() = %08x\n", result);
return 1; return 1;
} }
return kIOReturnSuccess; return kIOReturnSuccess;
} }
@ -331,7 +330,7 @@ kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *ou
size_t structureOutputSize; size_t structureOutputSize;
structureInputSize = sizeof(SMCKeyData_t); structureInputSize = sizeof(SMCKeyData_t);
structureOutputSize = sizeof(SMCKeyData_t); structureOutputSize = sizeof(SMCKeyData_t);
return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize); return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize);
} }
@ -342,42 +341,42 @@ kern_return_t SMCGetKeyInfo(UInt32 key, SMCKeyData_keyInfo_t* keyInfo, io_connec
SMCKeyData_t outputStructure; SMCKeyData_t outputStructure;
kern_return_t result = kIOReturnSuccess; kern_return_t result = kIOReturnSuccess;
int i = 0; int i = 0;
OSSpinLockLock(&g_keyInfoSpinLock); os_unfair_lock_lock(&g_keyInfoSpinLock);
for (; i < g_keyInfoCacheCount; ++i) for (; i < g_keyInfoCacheCount; ++i)
{ {
if (key == g_keyInfoCache[i].key) if (key == g_keyInfoCache[i].key)
{ {
*keyInfo = g_keyInfoCache[i].keyInfo; *keyInfo = g_keyInfoCache[i].keyInfo;
break; break;
} }
} }
if (i == g_keyInfoCacheCount) if (i == g_keyInfoCacheCount)
{ {
// Not in cache, must look it up. // Not in cache, must look it up.
memset(&inputStructure, 0, sizeof(inputStructure)); memset(&inputStructure, 0, sizeof(inputStructure));
memset(&outputStructure, 0, sizeof(outputStructure)); memset(&outputStructure, 0, sizeof(outputStructure));
inputStructure.key = key; inputStructure.key = key;
inputStructure.data8 = SMC_CMD_READ_KEYINFO; inputStructure.data8 = SMC_CMD_READ_KEYINFO;
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure, conn); result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure, conn);
if (result == kIOReturnSuccess) if (result == kIOReturnSuccess)
{ {
*keyInfo = outputStructure.keyInfo; *keyInfo = outputStructure.keyInfo;
if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE) if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE)
{ {
g_keyInfoCache[g_keyInfoCacheCount].key = key; g_keyInfoCache[g_keyInfoCacheCount].key = key;
g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo; g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo;
++g_keyInfoCacheCount; ++g_keyInfoCacheCount;
} }
} }
} }
OSSpinLockUnlock(&g_keyInfoSpinLock); os_unfair_lock_unlock(&g_keyInfoSpinLock);
return result; return result;
} }
@ -386,33 +385,33 @@ kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn)
kern_return_t result; kern_return_t result;
SMCKeyData_t inputStructure; SMCKeyData_t inputStructure;
SMCKeyData_t outputStructure; SMCKeyData_t outputStructure;
memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&inputStructure, 0, sizeof(SMCKeyData_t));
memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t));
memset(val, 0, sizeof(SMCVal_t)); memset(val, 0, sizeof(SMCVal_t));
inputStructure.key = _strtoul(key, 4, 16); inputStructure.key = _strtoul(key, 4, 16);
sprintf(val->key, key); sprintf(val->key, "%s", key);
result = SMCGetKeyInfo(inputStructure.key, &outputStructure.keyInfo, conn); result = SMCGetKeyInfo(inputStructure.key, &outputStructure.keyInfo, conn);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
{ {
return result; return result;
} }
val->dataSize = outputStructure.keyInfo.dataSize; val->dataSize = outputStructure.keyInfo.dataSize;
_ultostr(val->dataType, outputStructure.keyInfo.dataType); _ultostr(val->dataType, outputStructure.keyInfo.dataType);
inputStructure.keyInfo.dataSize = val->dataSize; inputStructure.keyInfo.dataSize = val->dataSize;
inputStructure.data8 = SMC_CMD_READ_BYTES; inputStructure.data8 = SMC_CMD_READ_BYTES;
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn); result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
{ {
return result; return result;
} }
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
return kIOReturnSuccess; return kIOReturnSuccess;
} }
@ -445,27 +444,27 @@ kern_return_t SMCWriteKey2(SMCVal_t writeVal, io_connect_t conn)
kern_return_t result; kern_return_t result;
SMCKeyData_t inputStructure; SMCKeyData_t inputStructure;
SMCKeyData_t outputStructure; SMCKeyData_t outputStructure;
SMCVal_t readVal; SMCVal_t readVal;
result = SMCReadKey2(writeVal.key, &readVal,conn); result = SMCReadKey2(writeVal.key, &readVal,conn);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
return result; return result;
if (readVal.dataSize != writeVal.dataSize) if (readVal.dataSize != writeVal.dataSize)
return kIOReturnError; return kIOReturnError;
memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&inputStructure, 0, sizeof(SMCKeyData_t));
memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t));
inputStructure.key = _strtoul(writeVal.key, 4, 16); inputStructure.key = _strtoul(writeVal.key, 4, 16);
inputStructure.data8 = SMC_CMD_WRITE_BYTES; inputStructure.data8 = SMC_CMD_WRITE_BYTES;
inputStructure.keyInfo.dataSize = writeVal.dataSize; inputStructure.keyInfo.dataSize = writeVal.dataSize;
memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes)); memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes));
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn); result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
return result; return result;
return kIOReturnSuccess; return kIOReturnSuccess;
} }
@ -477,7 +476,7 @@ kern_return_t SMCWriteKey(SMCVal_t writeVal)
UInt32 SMCReadIndexCount(void) UInt32 SMCReadIndexCount(void)
{ {
SMCVal_t val; SMCVal_t val;
SMCReadKey("#KEY", &val); SMCReadKey("#KEY", &val);
return _strtoul((char *)val.bytes, val.dataSize, 10); return _strtoul((char *)val.bytes, val.dataSize, 10);
} }
@ -487,31 +486,31 @@ kern_return_t SMCPrintAll(void)
kern_return_t result; kern_return_t result;
SMCKeyData_t inputStructure; SMCKeyData_t inputStructure;
SMCKeyData_t outputStructure; SMCKeyData_t outputStructure;
int totalKeys, i; int totalKeys, i;
UInt32Char_t key; UInt32Char_t key;
SMCVal_t val; SMCVal_t val;
totalKeys = SMCReadIndexCount(); totalKeys = SMCReadIndexCount();
for (i = 0; i < totalKeys; i++) for (i = 0; i < totalKeys; i++)
{ {
memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&inputStructure, 0, sizeof(SMCKeyData_t));
memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t));
memset(&val, 0, sizeof(SMCVal_t)); memset(&val, 0, sizeof(SMCVal_t));
inputStructure.data8 = SMC_CMD_READ_INDEX; inputStructure.data8 = SMC_CMD_READ_INDEX;
inputStructure.data32 = i; inputStructure.data32 = i;
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
continue; continue;
_ultostr(key, outputStructure.key); _ultostr(key, outputStructure.key);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printVal(val); printVal(val);
} }
return kIOReturnSuccess; return kIOReturnSuccess;
} }
@ -523,18 +522,18 @@ float getFloatFromVal(SMCVal_t val)
if (val.dataSize > 0) if (val.dataSize > 0)
{ {
if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4) { if (strcmp(val.dataType, DATATYPE_FLT) == 0 && val.dataSize == 4) {
memcpy(&fval,val.bytes,sizeof(float)); memcpy(&fval,val.bytes,sizeof(float));
} }
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2) { else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2) {
fval = _strtof(val.bytes, val.dataSize, 2); fval = _strtof(val.bytes, val.dataSize, 2);
} }
else if (strcmp(val.dataType, DATATYPE_UINT16) == 0 && val.dataSize == 2) { else if (strcmp(val.dataType, DATATYPE_UINT16) == 0 && val.dataSize == 2) {
fval = (float)_strtoul((char *)val.bytes, val.dataSize, 10); fval = (float)_strtoul((char *)val.bytes, val.dataSize, 10);
} }
else if (strcmp(val.dataType, DATATYPE_UINT8) == 0 && val.dataSize == 1) { else if (strcmp(val.dataType, DATATYPE_UINT8) == 0 && val.dataSize == 1) {
fval = (float)_strtoul((char *)val.bytes, val.dataSize, 10); fval = (float)_strtoul((char *)val.bytes, val.dataSize, 10);
} }
} }
return fval; return fval;
@ -546,54 +545,54 @@ kern_return_t SMCPrintFans(void)
SMCVal_t val; SMCVal_t val;
UInt32Char_t key; UInt32Char_t key;
int totalFans, i; int totalFans, i;
result = SMCReadKey("FNum", &val); result = SMCReadKey("FNum", &val);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
return kIOReturnError; return kIOReturnError;
totalFans = _strtoul((char *)val.bytes, val.dataSize, 10); totalFans = _strtoul((char *)val.bytes, val.dataSize, 10);
printf("Total fans in system: %d\n", totalFans); printf("Total fans in system: %d\n", totalFans);
for (i = 0; i < totalFans; i++) for (i = 0; i < totalFans; i++)
{ {
printf("\nFan #%d:\n", i); printf("\nFan #%d:\n", i);
sprintf(key, "F%cID", fannum[i]); sprintf(key, "F%cID", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
if(val.dataSize > 0) { if(val.dataSize > 0) {
printf(" Fan ID : %s\n", val.bytes+4); printf(" Fan ID : %s\n", val.bytes+4);
} }
sprintf(key, "F%cAc", fannum[i]); sprintf(key, "F%cAc", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printf(" Current speed : %.0f\n", getFloatFromVal(val)); printf(" Current speed : %.0f\n", getFloatFromVal(val));
sprintf(key, "F%cMn", fannum[i]); sprintf(key, "F%cMn", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printf(" Minimum speed: %.0f\n", getFloatFromVal(val)); printf(" Minimum speed: %.0f\n", getFloatFromVal(val));
sprintf(key, "F%cMx", fannum[i]); sprintf(key, "F%cMx", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printf(" Maximum speed: %.0f\n", getFloatFromVal(val)); printf(" Maximum speed: %.0f\n", getFloatFromVal(val));
sprintf(key, "F%cSf", fannum[i]); sprintf(key, "F%cSf", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printf(" Safe speed : %.0f\n", getFloatFromVal(val)); printf(" Safe speed : %.0f\n", getFloatFromVal(val));
sprintf(key, "F%cTg", fannum[i]); sprintf(key, "F%cTg", fannum[i]);
SMCReadKey(key, &val); SMCReadKey(key, &val);
printf(" Target speed : %.0f\n", getFloatFromVal(val)); printf(" Target speed : %.0f\n", getFloatFromVal(val));
SMCReadKey("FS! ", &val); SMCReadKey("FS! ", &val);
if(val.dataSize > 0) { if(val.dataSize > 0) {
if ((_strtoul((char *)val.bytes, 2, 16) & (1 << i)) == 0) if ((_strtoul((char *)val.bytes, 2, 16) & (1 << i)) == 0)
printf(" Mode : auto\n"); printf(" Mode : auto\n");
else else
printf(" Mode : forced\n"); printf(" Mode : forced\n");
} }
else { else {
sprintf(key, "F%dMd", i); sprintf(key, "F%dMd", i);
SMCReadKey(key, &val); SMCReadKey(key, &val);
if (getFloatFromVal(val)) if (getFloatFromVal(val))
printf(" Mode : forced\n"); printf(" Mode : forced\n");
else else
printf(" Mode : auto\n"); printf(" Mode : auto\n");
} }
} }
return kIOReturnSuccess; return kIOReturnSuccess;
} }
@ -610,28 +609,28 @@ kern_return_t SMCPrintTemps(void)
totalKeys = SMCReadIndexCount(); totalKeys = SMCReadIndexCount();
for (i = 0; i < totalKeys; i++) for (i = 0; i < totalKeys; i++)
{ {
memset(&inputStructure, 0, sizeof(SMCKeyData_t)); memset(&inputStructure, 0, sizeof(SMCKeyData_t));
memset(&outputStructure, 0, sizeof(SMCKeyData_t)); memset(&outputStructure, 0, sizeof(SMCKeyData_t));
memset(&val, 0, sizeof(SMCVal_t)); memset(&val, 0, sizeof(SMCVal_t));
inputStructure.data8 = SMC_CMD_READ_INDEX; inputStructure.data8 = SMC_CMD_READ_INDEX;
inputStructure.data32 = i; inputStructure.data32 = i;
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
continue; continue;
_ultostr(key, outputStructure.key); _ultostr(key, outputStructure.key);
if ( key[0] != 'T' ) if ( key[0] != 'T' )
continue; continue;
SMCReadKey(key, &val); SMCReadKey(key, &val);
//printVal(val); //printVal(val);
if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2) { if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2) {
printf("%-4s ", val.key); printf("%-4s ", val.key);
printSP78(val); printSP78(val);
printf("\n"); printf("\n");
} }
} }
return kIOReturnSuccess; return kIOReturnSuccess;
@ -661,16 +660,16 @@ kern_return_t SMCWriteSimple(UInt32Char_t key, char *wvalue, io_connect_t conn)
char c[3]; char c[3];
for (i = 0; i < strlen(wvalue); i++) for (i = 0; i < strlen(wvalue); i++)
{ {
sprintf(c, "%c%c", wvalue[i * 2], wvalue[(i * 2) + 1]); sprintf(c, "%c%c", wvalue[i * 2], wvalue[(i * 2) + 1]);
val.bytes[i] = (int) strtol(c, NULL, 16); val.bytes[i] = (int) strtol(c, NULL, 16);
} }
val.dataSize = i / 2; val.dataSize = i / 2;
sprintf(val.key, key); sprintf(val.key, "%s", key);
result = SMCWriteKey2(val, conn); result = SMCWriteKey2(val, conn);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCWriteKey() = %08x\n", result); printf("Error: SMCWriteKey() = %08x\n", result);
return result; return result;
} }
@ -678,119 +677,116 @@ int main(int argc, char *argv[])
{ {
int c; int c;
extern char *optarg; extern char *optarg;
kern_return_t result; kern_return_t result;
int op = OP_NONE; int op = OP_NONE;
UInt32Char_t key = { 0 }; UInt32Char_t key = { 0 };
SMCVal_t val; SMCVal_t val;
while ((c = getopt(argc, argv, "fthk:lrw:v")) != -1) while ((c = getopt(argc, argv, "fthk:lrw:v")) != -1)
{ {
switch(c) switch(c)
{ {
case 'f': case 'f':
op = OP_READ_FAN; op = OP_READ_FAN;
break; break;
case 't': case 't':
op = OP_READ_TEMPS; op = OP_READ_TEMPS;
break; break;
case 'k': case 'k':
strncpy(key, optarg, sizeof(key)); //fix for buffer overflow strncpy(key, optarg, sizeof(key)); //fix for buffer overflow
key[sizeof(key) - 1] = '\0'; key[sizeof(key) - 1] = '\0';
break; break;
case 'l': case 'l':
op = OP_LIST; op = OP_LIST;
break; break;
case 'r': case 'r':
op = OP_READ; op = OP_READ;
break; break;
case 'v': case 'v':
printf("%s\n", VERSION); printf("%s\n", VERSION);
return 0; return 0;
break; break;
case 'w': case 'w':
op = OP_WRITE; op = OP_WRITE;
{ {
int i; int i;
char c[3]; char c[3];
for (i = 0; i < strlen(optarg); i++) for (i = 0; i < strlen(optarg); i++)
{ {
sprintf(c, "%c%c", optarg[i * 2], optarg[(i * 2) + 1]); sprintf(c, "%c%c", optarg[i * 2], optarg[(i * 2) + 1]);
val.bytes[i] = (int) strtol(c, NULL, 16); val.bytes[i] = (int) strtol(c, NULL, 16);
} }
val.dataSize = i / 2; val.dataSize = i / 2;
if ((val.dataSize * 2) != strlen(optarg)) if ((val.dataSize * 2) != strlen(optarg))
{ {
printf("Error: value is not valid\n"); printf("Error: value is not valid\n");
return 1; return 1;
} }
} }
break; break;
case 'h': case 'h':
case '?': case '?':
op = OP_NONE; op = OP_NONE;
break; break;
} }
} }
if (op == OP_NONE) if (op == OP_NONE)
{ {
usage(argv[0]); usage(argv[0]);
return 1; return 1;
} }
smc_init(); smc_init();
switch(op) switch(op)
{ {
case OP_LIST: case OP_LIST:
result = SMCPrintAll(); result = SMCPrintAll();
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCPrintAll() = %08x\n", result); printf("Error: SMCPrintAll() = %08x\n", result);
break; break;
case OP_READ: case OP_READ:
if (strlen(key) > 0) if (strlen(key) > 0)
{ {
result = SMCReadKey(key, &val); result = SMCReadKey(key, &val);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCReadKey() = %08x\n", result); printf("Error: SMCReadKey() = %08x\n", result);
else else
printVal(val); printVal(val);
} }
else else
{ {
printf("Error: specify a key to read\n"); printf("Error: specify a key to read\n");
} }
break; break;
case OP_READ_FAN: case OP_READ_FAN:
result = SMCPrintFans(); result = SMCPrintFans();
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCPrintFans() = %08x\n", result); printf("Error: SMCPrintFans() = %08x\n", result);
break; break;
case OP_READ_TEMPS: case OP_READ_TEMPS:
result = SMCPrintTemps(); result = SMCPrintTemps();
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCPrintFans() = %08x\n", result); printf("Error: SMCPrintFans() = %08x\n", result);
break; break;
case OP_WRITE: case OP_WRITE:
if (strlen(key) > 0) if (strlen(key) > 0)
{ {
sprintf(val.key, key); sprintf(val.key, "%s", key);
result = SMCWriteKey(val); result = SMCWriteKey(val);
if (result != kIOReturnSuccess) if (result != kIOReturnSuccess)
printf("Error: SMCWriteKey() = %08x\n", result); printf("Error: SMCWriteKey() = %08x\n", result);
} }
else else
{ {
printf("Error: specify a key to write\n"); printf("Error: specify a key to write\n");
} }
break; break;
} }
smc_close(); smc_close();
return 0; return 0;
} }
#endif //#ifdef CMD_TOOL #endif //#ifdef CMD_TOOL