fix: use iowrite8 for byte-sized MMIO registers in applesmc (#43)

The iomem_write_smc, iomem_read_smc, and iomem_get_smc_key_type
functions used iowrite32 to write to byte-sized registers at
non-aligned addresses (KEY_DATA_LEN at 0x7D, KEY_SMC_ID at 0x7E,
KEY_CMD at 0x7F). On some T2 Macs (confirmed on MacBook Air 8,1),
the 32-bit writes at these consecutive addresses cause the T2 SMC
to receive corrupted data, resulting in SmcKeySizeMismatch (error
0x87) on every write operation.

This made fan control via t2fanrd completely non-functional since
the F0Md (fan manual mode) key could never be written.

Fix by using iowrite8 for these byte-sized registers, matching the
ioread8 already used to read them. The 4-byte KEY_NAME register at
0x78 correctly remains iowrite32.

Tested on MacBook Air 8,1 (T2) with kernel 6.18.13 - fan control
works after this fix.
This commit is contained in:
Federico Sapuppo
2026-04-07 06:54:54 -03:00
committed by GitHub
parent 122588cfde
commit da3e8faa7f
@@ -102,8 +102,8 @@ index 5442897e3..435541f9f 100644
+
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite8(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;
@@ -145,8 +145,8 @@ index 5442897e3..435541f9f 100644
+
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite8(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;
@@ -176,9 +176,9 @@ index 5442897e3..435541f9f 100644
+ iomem_clear_status(smc);
+ iowrite32(key_int, smc->iomem_base + APPLESMC_IOMEM_KEY_NAME);
+ memcpy_toio(smc->iomem_base + APPLESMC_IOMEM_KEY_DATA, buffer, len);
+ iowrite32(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN);
+ iowrite32(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite32(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+ iowrite8(len, smc->iomem_base + APPLESMC_IOMEM_KEY_DATA_LEN);
+ iowrite8(0, smc->iomem_base + APPLESMC_IOMEM_KEY_SMC_ID);
+ iowrite8(cmd, smc->iomem_base + APPLESMC_IOMEM_KEY_CMD);
+
+ if (iomem_wait_read(smc))
+ return -EIO;