Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141904070
D54441.id169373.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D54441.id169373.diff
View Options
diff --git a/share/man/man4/asmc.4 b/share/man/man4/asmc.4
--- a/share/man/man4/asmc.4
+++ b/share/man/man4/asmc.4
@@ -23,7 +23,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd April 2, 2019
+.Dd January 8, 2026
.Dt ASMC 4
.Os
.Sh NAME
@@ -110,6 +110,44 @@
respectively.
.Pp
All values are in RPM.
+.Sh RAW SMC KEY ACCESS
+The
+.Va dev.asmc.%d.raw
+sysctl tree provides direct access to arbitrary SMC keys for debugging
+and hardware exploration.
+This interface enables reading and writing any SMC key by name,
+allowing discovery of undocumented sensors and hardware controls.
+.Pp
+To use the raw SMC interface:
+.Bl -enum -offset indent
+.It
+Set the desired 4-character SMC key name:
+.Bd -literal -offset indent
+sysctl dev.asmc.0.raw.key=AUPO
+.Ed
+.It
+Read the key value as a hexadecimal string:
+.Bd -literal -offset indent
+sysctl dev.asmc.0.raw.value
+.Ed
+.It
+Write a new value as a hexadecimal string:
+.Bd -literal -offset indent
+sysctl dev.asmc.0.raw.value=01
+.Ed
+.El
+.Pp
+The key type and length are automatically detected when setting a key name.
+The
+.Va dev.asmc.%d.raw.len
+and
+.Va dev.asmc.%d.raw.type
+sysctls provide the detected length and 4-character type code.
+.Pp
+.Sy Warning :
+Writing incorrect values to SMC keys can cause system instability or
+hardware damage.
+This interface is intended for advanced users and developers only.
.Sh SUDDEN MOTION SENSOR
The Sudden Motion Sensor (SMS for short) is a device that detects
laptop movement and notifies the operating system via an interrupt.
diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -109,6 +109,13 @@
static int asmc_mbp_sysctl_light_control(SYSCTL_HANDLER_ARGS);
static int asmc_mbp_sysctl_light_left_10byte(SYSCTL_HANDLER_ARGS);
+/* Raw key access */
+static int asmc_key_getinfo(device_t, const char *, uint8_t *, char *);
+static int asmc_raw_key_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_raw_value_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_raw_len_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_raw_type_sysctl(SYSCTL_HANDLER_ARGS);
+
struct asmc_model {
const char *smc_model; /* smbios.system.product env var. */
const char *smc_desc; /* driver description */
@@ -716,6 +723,41 @@
"Keyboard backlight brightness control");
}
+ /*
+ * Raw SMC key access for debugging.
+ */
+ sc->sc_raw_tree = SYSCTL_ADD_NODE(sysctlctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+ "raw", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Raw SMC key access");
+
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sc->sc_raw_tree),
+ OID_AUTO, "key",
+ CTLTYPE_STRING | CTLFLAG_RW,
+ dev, 0, asmc_raw_key_sysctl, "A",
+ "SMC key name (4 chars)");
+
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sc->sc_raw_tree),
+ OID_AUTO, "value",
+ CTLTYPE_STRING | CTLFLAG_RW,
+ dev, 0, asmc_raw_value_sysctl, "A",
+ "SMC key value (hex string)");
+
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sc->sc_raw_tree),
+ OID_AUTO, "len",
+ CTLTYPE_U8 | CTLFLAG_RW,
+ dev, 0, asmc_raw_len_sysctl, "CU",
+ "SMC key value length");
+
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sc->sc_raw_tree),
+ OID_AUTO, "type",
+ CTLTYPE_STRING | CTLFLAG_RD,
+ dev, 0, asmc_raw_type_sysctl, "A",
+ "SMC key type (4 chars)");
+
if (model->smc_sms_x == NULL)
goto nosms;
@@ -1151,6 +1193,162 @@
}
#endif
+/*
+ * Get key info (length and type) from SMC using command 0x13.
+ * Returns 0 on success, -1 on failure.
+ * If len is non-NULL, stores the key's value length.
+ * If type is non-NULL, stores the 4-char type string (must be at least 5 bytes).
+ */
+static int
+asmc_key_getinfo(device_t dev, const char *key, uint8_t *len, char *type)
+{
+ struct asmc_softc *sc = device_get_softc(dev);
+ uint8_t info[6];
+ int i, error;
+
+ mtx_lock_spin(&sc->sc_mtx);
+
+ if (asmc_command(dev, 0x13)) {
+ mtx_unlock_spin(&sc->sc_mtx);
+ return (-1);
+ }
+
+ for (i = 0; i < 4; i++) {
+ ASMC_DATAPORT_WRITE(sc, key[i]);
+ if (asmc_wait(dev, 0x04)) {
+ mtx_unlock_spin(&sc->sc_mtx);
+ return (-1);
+ }
+ }
+
+ ASMC_DATAPORT_WRITE(sc, 6);
+
+ for (i = 0; i < 6; i++) {
+ if (asmc_wait(dev, 0x05)) {
+ mtx_unlock_spin(&sc->sc_mtx);
+ return (-1);
+ }
+ info[i] = ASMC_DATAPORT_READ(sc);
+ }
+
+ error = 0;
+ mtx_unlock_spin(&sc->sc_mtx);
+
+ if (error == 0) {
+ if (len != NULL)
+ *len = info[0];
+ if (type != NULL) {
+ for (i = 0; i < 4; i++)
+ type[i] = info[i + 1];
+ type[4] = '\0';
+ }
+ }
+ return (error);
+}
+
+/*
+ * Raw SMC key access sysctls - enables reading/writing any SMC key by name
+ * Usage:
+ * sysctl dev.asmc.0.raw.key=AUPO # Set key, auto-detects length
+ * sysctl dev.asmc.0.raw.value # Read current value (hex)
+ * sysctl dev.asmc.0.raw.value=01 # Write new value (hex)
+ */
+static int
+asmc_raw_key_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t) arg1;
+ struct asmc_softc *sc = device_get_softc(dev);
+ char newkey[5];
+ uint8_t keylen;
+ int error;
+
+ strlcpy(newkey, sc->sc_rawkey, sizeof(newkey));
+ error = sysctl_handle_string(oidp, newkey, sizeof(newkey), req);
+ if (error || req->newptr == NULL)
+ return (error);
+
+ if (strlen(newkey) != 4)
+ return (EINVAL);
+
+ /* Get key info to auto-detect length and type */
+ if (asmc_key_getinfo(dev, newkey, &keylen, sc->sc_rawtype) != 0)
+ return (ENOENT);
+
+ if (keylen > ASMC_MAXVAL)
+ keylen = ASMC_MAXVAL;
+
+ strlcpy(sc->sc_rawkey, newkey, sizeof(sc->sc_rawkey));
+ sc->sc_rawlen = keylen;
+ memset(sc->sc_rawval, 0, sizeof(sc->sc_rawval));
+
+ /* Read the key value */
+ asmc_key_read(dev, sc->sc_rawkey, sc->sc_rawval, sc->sc_rawlen);
+
+ return (0);
+}
+
+static int
+asmc_raw_value_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t) arg1;
+ struct asmc_softc *sc = device_get_softc(dev);
+ char hexbuf[ASMC_MAXVAL * 2 + 1];
+ int error, i;
+
+ /* Refresh from SMC */
+ if (sc->sc_rawkey[0] != '\0') {
+ asmc_key_read(dev, sc->sc_rawkey, sc->sc_rawval,
+ sc->sc_rawlen > 0 ? sc->sc_rawlen : ASMC_MAXVAL);
+ }
+
+ /* Format as hex string */
+ for (i = 0; i < sc->sc_rawlen && i < ASMC_MAXVAL; i++)
+ snprintf(hexbuf + i * 2, 3, "%02x", sc->sc_rawval[i]);
+ hexbuf[i * 2] = '\0';
+
+ error = sysctl_handle_string(oidp, hexbuf, sizeof(hexbuf), req);
+ if (error || req->newptr == NULL)
+ return (error);
+
+ /* Parse hex and write */
+ if (sc->sc_rawkey[0] == '\0')
+ return (EINVAL);
+
+ memset(sc->sc_rawval, 0, sizeof(sc->sc_rawval));
+ for (i = 0; i < sc->sc_rawlen && hexbuf[i * 2] &&
+ hexbuf[i * 2 + 1]; i++) {
+ unsigned int val;
+ char tmp[3] = { hexbuf[i * 2], hexbuf[i * 2 + 1], 0 };
+ if (sscanf(tmp, "%02x", &val) == 1)
+ sc->sc_rawval[i] = (uint8_t)val;
+ }
+
+ if (asmc_key_write(dev, sc->sc_rawkey, sc->sc_rawval,
+ sc->sc_rawlen) != 0)
+ return (EIO);
+
+ return (0);
+}
+
+static int
+asmc_raw_len_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t) arg1;
+ struct asmc_softc *sc = device_get_softc(dev);
+
+ return (sysctl_handle_8(oidp, &sc->sc_rawlen, 0, req));
+}
+
+static int
+asmc_raw_type_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t) arg1;
+ struct asmc_softc *sc = device_get_softc(dev);
+
+ return (sysctl_handle_string(oidp, sc->sc_rawtype,
+ sizeof(sc->sc_rawtype), req));
+}
+
static int
asmc_key_write(device_t dev, const char *key, uint8_t *buf, uint8_t len)
{
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -28,6 +28,7 @@
*/
#define ASMC_MAXFANS 6
+#define ASMC_MAXVAL 32 /* Maximum SMC value size */
struct asmc_softc {
device_t sc_dev;
@@ -51,6 +52,12 @@
struct taskqueue *sc_sms_tq;
struct task sc_sms_task;
uint8_t sc_sms_intr_works;
+ /* Raw key access */
+ struct sysctl_oid *sc_raw_tree;
+ char sc_rawkey[5]; /* 4-char key + NUL */
+ uint8_t sc_rawval[ASMC_MAXVAL];
+ uint8_t sc_rawlen;
+ char sc_rawtype[5]; /* 4-char type + NUL */
};
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 13, 7:18 AM (6 h, 33 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27625466
Default Alt Text
D54441.id169373.diff (9 KB)
Attached To
Mode
D54441: asmc: add raw SMC key read/write interface
Attached
Detach File
Event Timeline
Log In to Comment