All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support
@ 2026-08-11 23:39 Arie Miller
  2026-08-11 23:39 ` [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration Arie Miller
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Arie Miller @ 2026-08-11 23:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel, Arie Miller

Add hardware monitoring support for ASUS ROG Ryujin III coolers.

Compared with the Ryujin II, the Ryujin III uses different offsets in
its status reports and a different cooler-duty channel. It also does not
expose the Ryujin II's external fan-controller channels. The first patch
moves those details into per-device configuration, and the second adds
the Extreme and EVA Edition variants. The third patch, authored by Will
Smith, adds the White Edition USB ID. Will confirmed his authorship
sign-off and tested that variant on his hardware.

The fourth patch rejects HID devices without per-device configuration
before that configuration is dereferenced. This prevents dynamic new_id
bindings from causing a NULL pointer dereference.

The Ryujin III implementation and White Edition were tested through the
linked project pull requests. The EVA Edition hardware was tested by me.

Codex using gpt-5.6-sol assisted with porting the changes to the current
hwmon tree, organizing the patch series, updating documentation and
commit messages, and running build, checkpatch, Sparse, and Sphinx
validation. I reviewed and tested the resulting changes on ROG Ryujin
III EVA Edition hardware.

The v2 series passes git diff --check and checkpatch --strict. The driver
object compiles in-tree with W=1 in both built-in and module
configurations, and Sparse reports no findings for either configuration.
The range-diff confirms that the first three patches are unchanged from
v1.

Changes in v2:
- Add a final patch validating per-device configuration, as requested by
  Guenter Roeck.
- Rebase the series onto the current hwmon-next branch.

v1: https://lore.kernel.org/r/20260807000107.1786892-1-renari@arimil.com


Arie Miller (3):
  hwmon: (asus_rog_ryujin) Add per-device configuration
  hwmon: (asus_rog_ryujin) Add ROG Ryujin III support
  hwmon: (asus_rog_ryujin) Handle missing driver data

Will Smith (1):
  hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition

 Documentation/hwmon/asus_rog_ryujin.rst | 25 ++++---
 drivers/hwmon/Kconfig                   |  4 +-
 drivers/hwmon/asus_rog_ryujin.c         | 96 ++++++++++++++++++-------
 3 files changed, 87 insertions(+), 38 deletions(-)

Range-diff against v1:
1:  af53cbee3303 = 1:  686fd2251bea hwmon: (asus_rog_ryujin) Add per-device configuration
2:  603a2e86b65c = 2:  68d87330a2f7 hwmon: (asus_rog_ryujin) Add ROG Ryujin III support
3:  0f4a66284361 = 3:  c3d95809f962 hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition
-:  ------------ > 4:  e9558b907537 hwmon: (asus_rog_ryujin) Handle missing driver data

base-commit: 54743b5ab981d686b885c3da639d4ed6cc995e8b
-- 
2.55.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration
  2026-08-11 23:39 [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support Arie Miller
@ 2026-08-11 23:39 ` Arie Miller
  2026-08-11 23:49   ` sashiko-bot
  2026-08-11 23:39 ` [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support Arie Miller
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Arie Miller @ 2026-08-11 23:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel, Arie Miller

Move model-specific report offsets and capabilities into a device
information structure. This prepares the driver for coolers which use
a different report layout or do not include the external fan
controller, while preserving the existing Ryujin II 360 behavior.

Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
---
 drivers/hwmon/asus_rog_ryujin.c | 72 ++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index 10a1f5aca988..b86b87e33615 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -18,15 +18,25 @@
 #define USB_VENDOR_ID_ASUS_ROG		0x0b05
 #define USB_PRODUCT_ID_RYUJIN_AIO	0x1988	/* ASUS ROG RYUJIN II 360 */
 
+struct rog_ryujin_device_info {
+	u8 temp_offset;
+	u8 pump_speed_offset;
+	u8 fan_speed_offset;
+	u8 duty_channel;
+	bool has_controller;
+};
+
+static const struct rog_ryujin_device_info rog_ryujin_ii_360_info = {
+	.temp_offset = 3,
+	.pump_speed_offset = 5,
+	.fan_speed_offset = 7,
+	.duty_channel = 0,
+	.has_controller = true,
+};
+
 #define STATUS_VALIDITY		1500	/* ms */
 #define MAX_REPORT_LENGTH	65
 
-/* Cooler status report offsets */
-#define RYUJIN_TEMP_SENSOR_1		3
-#define RYUJIN_TEMP_SENSOR_2		4
-#define RYUJIN_PUMP_SPEED		5
-#define RYUJIN_INTERNAL_FAN_SPEED	7
-
 /* Cooler duty report offsets */
 #define RYUJIN_PUMP_DUTY		4
 #define RYUJIN_INTERNAL_FAN_DUTY	5
@@ -81,6 +91,7 @@ static const char *const rog_ryujin_speed_label[] = {
 struct rog_ryujin_data {
 	struct hid_device *hdev;
 	struct device *hwmon_dev;
+	const struct rog_ryujin_device_info *info;
 	/* For reinitializing the completions below */
 	spinlock_t status_report_request_lock;
 	struct completion cooler_status_received;
@@ -112,6 +123,8 @@ static int rog_ryujin_pwm_to_percent(long val)
 static umode_t rog_ryujin_is_visible(const void *data,
 				     enum hwmon_sensor_types type, u32 attr, int channel)
 {
+	const struct rog_ryujin_data *priv = data;
+
 	switch (type) {
 	case hwmon_temp:
 		switch (attr) {
@@ -123,6 +136,8 @@ static umode_t rog_ryujin_is_visible(const void *data,
 		}
 		break;
 	case hwmon_fan:
+		if (channel >= 2 && !priv->info->has_controller)
+			return 0;
 		switch (attr) {
 		case hwmon_fan_label:
 		case hwmon_fan_input:
@@ -132,6 +147,8 @@ static umode_t rog_ryujin_is_visible(const void *data,
 		}
 		break;
 	case hwmon_pwm:
+		if (channel >= 2 && !priv->info->has_controller)
+			return 0;
 		switch (attr) {
 		case hwmon_pwm_input:
 			return 0644;
@@ -198,12 +215,14 @@ static int rog_ryujin_get_status(struct rog_ryujin_data *priv)
 	if (ret < 0)
 		return ret;
 
-	/* Retrieve controller status (speeds) */
-	ret =
-	    rog_ryujin_execute_cmd(priv, get_controller_speed_cmd, GET_CMD_LENGTH,
-				   &priv->controller_status_received);
-	if (ret < 0)
-		return ret;
+	if (priv->info->has_controller) {
+		/* Retrieve controller status (speeds) */
+		ret = rog_ryujin_execute_cmd(priv, get_controller_speed_cmd,
+					     GET_CMD_LENGTH,
+					     &priv->controller_status_received);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* Retrieve cooler duty */
 	ret =
@@ -212,12 +231,14 @@ static int rog_ryujin_get_status(struct rog_ryujin_data *priv)
 	if (ret < 0)
 		return ret;
 
-	/* Retrieve controller duty */
-	ret =
-	    rog_ryujin_execute_cmd(priv, get_controller_duty_cmd, GET_CMD_LENGTH,
-				   &priv->controller_duty_received);
-	if (ret < 0)
-		return ret;
+	if (priv->info->has_controller) {
+		/* Retrieve controller duty */
+		ret = rog_ryujin_execute_cmd(priv, get_controller_duty_cmd,
+					     GET_CMD_LENGTH,
+					     &priv->controller_duty_received);
+		if (ret < 0)
+			return ret;
+	}
 
 	priv->updated = jiffies;
 	return 0;
@@ -289,6 +310,7 @@ static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel
 			return ret;
 
 		memcpy(set_cmd, set_cooler_duty_cmd, SET_CMD_LENGTH);
+		set_cmd[2] = priv->info->duty_channel;
 
 		/* Cooler duties are set as 0-100% */
 		val = rog_ryujin_pwm_to_percent(val);
@@ -394,10 +416,12 @@ static int rog_ryujin_raw_event(struct hid_device *hdev, struct hid_report *repo
 
 	if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
 		/* Received coolant temp and speeds of pump and internal fan */
-		priv->temp_input[0] =
-		    data[RYUJIN_TEMP_SENSOR_1] * 1000 + data[RYUJIN_TEMP_SENSOR_2] * 100;
-		priv->speed_input[0] = get_unaligned_le16(data + RYUJIN_PUMP_SPEED);
-		priv->speed_input[1] = get_unaligned_le16(data + RYUJIN_INTERNAL_FAN_SPEED);
+		priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
+			data[priv->info->temp_offset + 1] * 100;
+		priv->speed_input[0] =
+			get_unaligned_le16(data + priv->info->pump_speed_offset);
+		priv->speed_input[1] =
+			get_unaligned_le16(data + priv->info->fan_speed_offset);
 
 		if (!completion_done(&priv->cooler_status_received))
 			complete_all(&priv->cooler_status_received);
@@ -476,6 +500,7 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
 		return -ENOMEM;
 
 	priv->hdev = hdev;
+	priv->info = (const struct rog_ryujin_device_info *)id->driver_data;
 	hid_set_drvdata(hdev, priv);
 
 	/*
@@ -546,7 +571,8 @@ static void rog_ryujin_remove(struct hid_device *hdev)
 }
 
 static const struct hid_device_id rog_ryujin_table[] = {
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO),
+	  .driver_data = (kernel_ulong_t)&rog_ryujin_ii_360_info },
 	{ }
 };
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support
  2026-08-11 23:39 [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support Arie Miller
  2026-08-11 23:39 ` [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration Arie Miller
@ 2026-08-11 23:39 ` Arie Miller
  2026-08-11 23:52   ` sashiko-bot
  2026-08-11 23:39 ` [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition Arie Miller
  2026-08-11 23:39 ` [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data Arie Miller
  3 siblings, 1 reply; 10+ messages in thread
From: Arie Miller @ 2026-08-11 23:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel, Arie Miller

The ROG Ryujin III uses different report offsets and a different
cooler-duty channel from the Ryujin II. It also lacks the separate
external fan controller supplied with the older model.

Add model data and USB IDs for the Extreme and EVA Edition variants.
Skip controller commands and hide the unavailable controller hwmon
channels for these devices. Update the driver documentation, Kconfig
text, and module description accordingly.

Link: https://github.com/aleksamagicka/asus_rog_ryujin-hwmon/pull/9
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
---
 Documentation/hwmon/asus_rog_ryujin.rst | 24 +++++++++++++-----------
 drivers/hwmon/Kconfig                   |  4 ++--
 drivers/hwmon/asus_rog_ryujin.c         | 18 ++++++++++++++++--
 3 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/Documentation/hwmon/asus_rog_ryujin.rst b/Documentation/hwmon/asus_rog_ryujin.rst
index 9f77da070022..cfdfe3712f19 100644
--- a/Documentation/hwmon/asus_rog_ryujin.rst
+++ b/Documentation/hwmon/asus_rog_ryujin.rst
@@ -6,6 +6,8 @@ Kernel driver asus_rog_ryujin
 Supported devices:
 
 * ASUS ROG RYUJIN II 360
+* ASUS ROG RYUJIN III EXTREME
+* ASUS ROG RYUJIN III EVA EDITION
 
 Author: Aleksa Savic
 
@@ -16,10 +18,10 @@ This driver enables hardware monitoring support for the listed ASUS ROG RYUJIN
 all-in-one CPU liquid coolers. Available sensors are pump, internal and external
 (controller) fan speed in RPM, their duties in PWM, as well as coolant temperature.
 
-Attaching external fans to the controller is optional and allows them to be
-controlled from the device. If not connected, the fan-related sensors will
-report zeroes. The controller is a separate hardware unit that comes bundled
-with the AIO and connects to it to allow fan control.
+The RYUJIN II includes a separate external fan controller. Attaching fans to
+the controller is optional and allows them to be controlled from the device.
+If not connected, the controller-related sensors will report zeroes. The
+RYUJIN III does not expose these controller channels.
 
 The addressable LCD screen is not supported in this driver and should
 be controlled through userspace tools.
@@ -33,15 +35,15 @@ supports hot swapping.
 Sysfs entries
 -------------
 
-=========== =============================================
+=========== ==========================================================
 fan1_input  Pump speed (in rpm)
 fan2_input  Internal fan speed (in rpm)
-fan3_input  External (controller) fan 1 speed (in rpm)
-fan4_input  External (controller) fan 2 speed (in rpm)
-fan5_input  External (controller) fan 3 speed (in rpm)
-fan6_input  External (controller) fan 4 speed (in rpm)
+fan3_input  External (controller) fan 1 speed (in rpm, RYUJIN II only)
+fan4_input  External (controller) fan 2 speed (in rpm, RYUJIN II only)
+fan5_input  External (controller) fan 3 speed (in rpm, RYUJIN II only)
+fan6_input  External (controller) fan 4 speed (in rpm, RYUJIN II only)
 temp1_input Coolant temperature (in millidegrees Celsius)
 pwm1        Pump duty
 pwm2        Internal fan duty
-pwm3        External (controller) fan duty
-=========== =============================================
+pwm3        External (controller) fan duty (RYUJIN II only)
+=========== ==========================================================
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 43418633e2e8..81a9a1d40eec 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -293,11 +293,11 @@ config SENSORS_ASC7621
 	  will be called asc7621.
 
 config SENSORS_ASUS_ROG_RYUJIN
-	tristate "ASUS ROG RYUJIN II 360 hardware monitoring driver"
+	tristate "ASUS ROG RYUJIN hardware monitoring driver"
 	depends on HID
 	help
 	  If you say yes here you get support for the fans and sensors of
-	  the ASUS ROG RYUJIN II 360 AIO CPU liquid cooler.
+	  supported ASUS ROG RYUJIN II and III AIO CPU liquid coolers.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called asus_rog_ryujin.
diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index b86b87e33615..5bc60c6036de 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * hwmon driver for Asus ROG Ryujin II 360 AIO cooler.
+ * hwmon driver for Asus ROG Ryujin AIO coolers.
  *
  * Copyright 2024 Aleksa Savic <savicaleksa83@gmail.com>
  */
@@ -17,6 +17,8 @@
 
 #define USB_VENDOR_ID_ASUS_ROG		0x0b05
 #define USB_PRODUCT_ID_RYUJIN_AIO	0x1988	/* ASUS ROG RYUJIN II 360 */
+#define USB_PRODUCT_ID_RYUJIN_III_EXTREME	0x1bcb
+#define USB_PRODUCT_ID_RYUJIN_III_EVA		0x1ade
 
 struct rog_ryujin_device_info {
 	u8 temp_offset;
@@ -34,6 +36,14 @@ static const struct rog_ryujin_device_info rog_ryujin_ii_360_info = {
 	.has_controller = true,
 };
 
+static const struct rog_ryujin_device_info rog_ryujin_iii_info = {
+	.temp_offset = 5,
+	.pump_speed_offset = 7,
+	.fan_speed_offset = 10,
+	.duty_channel = 1,
+	.has_controller = false,
+};
+
 #define STATUS_VALIDITY		1500	/* ms */
 #define MAX_REPORT_LENGTH	65
 
@@ -573,6 +583,10 @@ static void rog_ryujin_remove(struct hid_device *hdev)
 static const struct hid_device_id rog_ryujin_table[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO),
 	  .driver_data = (kernel_ulong_t)&rog_ryujin_ii_360_info },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_EXTREME),
+	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_EVA),
+	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
 	{ }
 };
 
@@ -602,4 +616,4 @@ module_exit(rog_ryujin_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
-MODULE_DESCRIPTION("Hwmon driver for Asus ROG Ryujin II 360 AIO cooler");
+MODULE_DESCRIPTION("Hwmon driver for Asus ROG Ryujin AIO coolers");
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition
  2026-08-11 23:39 [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support Arie Miller
  2026-08-11 23:39 ` [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration Arie Miller
  2026-08-11 23:39 ` [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support Arie Miller
@ 2026-08-11 23:39 ` Arie Miller
  2026-08-11 23:51   ` sashiko-bot
  2026-08-11 23:39 ` [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data Arie Miller
  3 siblings, 1 reply; 10+ messages in thread
From: Arie Miller @ 2026-08-11 23:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel, Arie Miller

From: Will Smith <github@notthatwillsmith.com>

The ROG Ryujin III White Edition uses the same report layout as the
other supported Ryujin III variants. Add its USB device ID and list it
in the driver documentation.

The device was tested with the driver on the author's hardware.

Link: https://github.com/aleksamagicka/asus_rog_ryujin-hwmon/pull/10
Signed-off-by: Will Smith <github@notthatwillsmith.com>
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
---
 Documentation/hwmon/asus_rog_ryujin.rst | 1 +
 drivers/hwmon/asus_rog_ryujin.c         | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/Documentation/hwmon/asus_rog_ryujin.rst b/Documentation/hwmon/asus_rog_ryujin.rst
index cfdfe3712f19..b0d7ce8dd921 100644
--- a/Documentation/hwmon/asus_rog_ryujin.rst
+++ b/Documentation/hwmon/asus_rog_ryujin.rst
@@ -8,6 +8,7 @@ Supported devices:
 * ASUS ROG RYUJIN II 360
 * ASUS ROG RYUJIN III EXTREME
 * ASUS ROG RYUJIN III EVA EDITION
+* ASUS ROG RYUJIN III WHITE EDITION
 
 Author: Aleksa Savic
 
diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index 5bc60c6036de..9b34c6e06bf7 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -19,6 +19,7 @@
 #define USB_PRODUCT_ID_RYUJIN_AIO	0x1988	/* ASUS ROG RYUJIN II 360 */
 #define USB_PRODUCT_ID_RYUJIN_III_EXTREME	0x1bcb
 #define USB_PRODUCT_ID_RYUJIN_III_EVA		0x1ade
+#define USB_PRODUCT_ID_RYUJIN_III_WHITE		0x1ada
 
 struct rog_ryujin_device_info {
 	u8 temp_offset;
@@ -587,6 +588,8 @@ static const struct hid_device_id rog_ryujin_table[] = {
 	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_EVA),
 	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_WHITE),
+	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
 	{ }
 };
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data
  2026-08-11 23:39 [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support Arie Miller
                   ` (2 preceding siblings ...)
  2026-08-11 23:39 ` [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition Arie Miller
@ 2026-08-11 23:39 ` Arie Miller
  2026-08-11 23:51   ` sashiko-bot
  2026-08-12  2:00   ` Guenter Roeck
  3 siblings, 2 replies; 10+ messages in thread
From: Arie Miller @ 2026-08-11 23:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel, Arie Miller

Handles an issue reported by Sashiko where an id could
be missing driver_data.

Link: https://lore.kernel.org/r/5a817284-a9f4-48b2-9f0f-802c5dc6963c@roeck-us.net
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
---
 drivers/hwmon/asus_rog_ryujin.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index 9b34c6e06bf7..702edb831394 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -506,6 +506,9 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
 	struct rog_ryujin_data *priv;
 	int ret;
 
+	if (!id->driver_data)
+		return -EINVAL;
+
 	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration
  2026-08-11 23:39 ` [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration Arie Miller
@ 2026-08-11 23:49   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-11 23:49 UTC (permalink / raw)
  To: Arie Miller; +Cc: linux-hwmon

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Critical] NULL pointer dereference when device is bound via sysfs `new_id`.

Pre-existing issues:
- [Critical] Out-of-bounds read in raw event handler due to missing size validation.
- [High] Data race on completion structure leading to missed wakeups.
--

--- Patch [1]: [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration ---
commit 471ae8f11e4ed856f2112cef2beadd2e4b019b6e
Author: Arie Miller <renari@arimil.com>

hwmon: (asus_rog_ryujin) Add per-device configuration

Move model-specific report offsets and capabilities into a device
information structure. This prepares the driver for coolers which use
a different report layout or do not include the external fan
controller, while preserving the existing Ryujin II 360 behavior.

> diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
> index 10a1f5aca988d..b86b87e33615d 100644
> --- a/drivers/hwmon/asus_rog_ryujin.c
> +++ b/drivers/hwmon/asus_rog_ryujin.c
[ ... ]
> @@ -394,10 +416,12 @@ static int rog_ryujin_raw_event(struct hid_device *hdev, struct hid_report *repo
>  
>  	if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
>  		/* Received coolant temp and speeds of pump and internal fan */
> -		priv->temp_input[0] =
> -		    data[RYUJIN_TEMP_SENSOR_1] * 1000 + data[RYUJIN_TEMP_SENSOR_2] * 100;
> -		priv->speed_input[0] = get_unaligned_le16(data + RYUJIN_PUMP_SPEED);
> -		priv->speed_input[1] = get_unaligned_le16(data + RYUJIN_INTERNAL_FAN_SPEED);
> +		priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
> +			data[priv->info->temp_offset + 1] * 100;

[Severity: Critical]
This is a pre-existing issue, but the driver appears to access data[0] and
other offsets without verifying the size of the buffer.

If a malicious device sends a truncated HID report, could this read past
the end of the allocated heap buffer since rog_ryujin_raw_event() extracts
values at offsets like priv->info->temp_offset without verifying that the
size parameter covers these bounds?

> +		priv->speed_input[0] =
> +			get_unaligned_le16(data + priv->info->pump_speed_offset);
> +		priv->speed_input[1] =
> +			get_unaligned_le16(data + priv->info->fan_speed_offset);
>  
>  		if (!completion_done(&priv->cooler_status_received))
>  			complete_all(&priv->cooler_status_received);

[Severity: High]
This isn't a bug introduced by this patch, but there seems to be a data
race on the completion structure between rog_ryujin_execute_cmd() and
rog_ryujin_raw_event().

In rog_ryujin_execute_cmd(), the driver attempts to protect the
reinit_completion() call using spin_lock_bh(&priv->status_report_request_lock).
However, spin_lock_bh() only disables softirqs on the local CPU.

Since rog_ryujin_raw_event() (running in softirq context on another CPU)
calls complete_all() without acquiring status_report_request_lock, could
this lockless write race directly with the locked increment, leading to
state corruption and sysfs read timeouts?

[ ... ]
> @@ -476,6 +500,7 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
>  		return -ENOMEM;
>  
>  	priv->hdev = hdev;
> +	priv->info = (const struct rog_ryujin_device_info *)id->driver_data;

[Severity: Critical]
If a user binds a new USB device ID using the sysfs new_id interface, the
HID subsystem creates a hid_device_id struct with a zero-initialized
driver_data field.

Does this mean id->driver_data can be NULL here? If so, when the hwmon
core calls rog_ryujin_is_visible() during registration, will it trigger a
NULL pointer dereference when evaluating !priv->info->has_controller?

>  	hid_set_drvdata(hdev, priv);
>  
>  	/*

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260811233943.319729-1-renari@arimil.com?part=1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data
  2026-08-11 23:39 ` [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data Arie Miller
@ 2026-08-11 23:51   ` sashiko-bot
  2026-08-12  2:00   ` Guenter Roeck
  1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-11 23:51 UTC (permalink / raw)
  To: Arie Miller; +Cc: linux-hwmon

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing size validation of incoming HID reports in `rog_ryujin_raw_event` leads to out-of-bounds heap reads.
- [Medium] Early sysfs interaction causes spurious `-ETIMEDOUT` errors because HID I/O is not started.
- [Medium] The `status_report_request_lock` spinlock provides no mutual exclusion against `rog_ryujin_raw_event`, leading to a race condition on completions.
--

--- Patch [4]: [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data ---
commit ec4154bc4d0c91156d0d07b375b65f694f8c0199
Author: Arie Miller <renari@arimil.com>

hwmon: (asus_rog_ryujin) Handle missing driver data

Handles an issue reported by Sashiko where an id could
be missing driver_data.

Link: https://lore.kernel.org/r/5a817284-a9f4-48b2-9f0f-802c5dc6963c@roeck-us.net

> diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
> index 9b34c6e06bf78..702edb8313945 100644
> --- a/drivers/hwmon/asus_rog_ryujin.c
> +++ b/drivers/hwmon/asus_rog_ryujin.c
> @@ -506,6 +506,9 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
>  	struct rog_ryujin_data *priv;
>  	int ret;
>  
> +	if (!id->driver_data)
> +		return -EINVAL;
> +
>  	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
>  	if (!priv)
>  		return -ENOMEM;

[Severity: High]
This isn't a bug introduced by this patch, but is there a missing size
validation in rog_ryujin_raw_event()?

If a malicious or malfunctioning HID device sends a short report matching the
expected prefix but lacking the required data fields, the size parameter
doesn't seem to be validated:

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_raw_event() {
    ...
	if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
		/* Received coolant temp and speeds of pump and internal fan */
		priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
    ...
}

Could accessing fixed and dynamic offsets here lead to an out-of-bounds heap
read, potentially resulting in a KASAN crash or leaking adjacent heap memory
contents?

[Severity: Medium]
This is a pre-existing issue, but can early sysfs interaction cause
spurious -ETIMEDOUT errors during device initialization?

The hwmon device is registered and exposed to userspace here:

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_probe() {
    ...
	priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "rog_ryujin",
							  priv, &rog_ryujin_chip_info, NULL);
    ...
}

If userspace accesses the hwmon sysfs attributes immediately after they are
created, but before the probe() callback returns, will incoming hardware
reports be rejected with -EBUSY because __hid_device_probe() holds
driver_input_lock?

Since HID I/O is not explicitly started before registering the hwmon device,
might this race condition lead to dropped HID events?

[Severity: Medium]
This isn't a bug introduced by this patch, but does the
status_report_request_lock spinlock actually protect the completion structures?

The spinlock is acquired to protect reinit_completion():

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_execute_cmd() {
    ...
	spin_lock_bh(&priv->status_report_request_lock);
	reinit_completion(status_completion);
	spin_unlock_bh(&priv->status_report_request_lock);
    ...
}

However, the event handler accesses and modifies the completion structures
without acquiring status_report_request_lock:

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_raw_event() {
    ...
	if (!completion_done(&priv->cooler_status_received))
		complete_all(&priv->cooler_status_received);
    ...
}

If complete_all() is called concurrently with reinit_completion() from a
userspace sysfs read/write, could this race condition corrupt the completion
done count and cause sysfs operations to fail with -ETIMEDOUT or return stale
data?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260811233943.319729-1-renari@arimil.com?part=4

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition
  2026-08-11 23:39 ` [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition Arie Miller
@ 2026-08-11 23:51   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-11 23:51 UTC (permalink / raw)
  To: Arie Miller; +Cc: linux-hwmon

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing bounds check on incoming HID report size in `rog_ryujin_raw_event` leading to an out-of-bounds heap read.
--

--- Patch [3]: [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition ---
commit b585240116bcd8eafe7d693a9003f8ad82dee763
Author: Will Smith <github@notthatwillsmith.com>

hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition

The ROG Ryujin III White Edition uses the same report layout as the
other supported Ryujin III variants. Add its USB device ID and list it
in the driver documentation.

Link: https://github.com/aleksamagicka/asus_rog_ryujin-hwmon/pull/10

> diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
> index 5bc60c6036de3..9b34c6e06bf78 100644
> --- a/drivers/hwmon/asus_rog_ryujin.c
> +++ b/drivers/hwmon/asus_rog_ryujin.c

[ ... ]

> @@ -587,6 +588,8 @@ static const struct hid_device_id rog_ryujin_table[] = {
>  	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_EVA),
>  	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },
> +	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_III_WHITE),
> +	  .driver_data = (kernel_ulong_t)&rog_ryujin_iii_info },

[Severity: High]
This is a pre-existing issue, but adding this device ID exposes the new
hardware to a missing bounds check in rog_ryujin_raw_event().

When the driver receives raw HID reports, it fails to validate the incoming
size parameter against the offsets it accesses:

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_raw_event() {
	...
	if (data[0] != RYUJIN_CMD_PREFIX)
		return 0;

	if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
		/* Received coolant temp and speeds of pump and internal fan */
		priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
			data[priv->info->temp_offset + 1] * 100;
	...
}

If a malicious USB device presents a HID descriptor declaring a very small
report size (e.g., 1 byte) and sends a 1-byte report, the driver
unconditionally accesses fixed offsets such as data[1] and, depending on the
device info, up to data[12].

Could this allow an out-of-bounds heap read where leaked kernel memory is
stored in variables like priv->temp_input and priv->speed_input, and then
exposed to userspace via the hwmon sysfs interface?

>  	{ }
>  };
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260811233943.319729-1-renari@arimil.com?part=3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support
  2026-08-11 23:39 ` [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support Arie Miller
@ 2026-08-11 23:52   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-08-11 23:52 UTC (permalink / raw)
  To: Arie Miller; +Cc: linux-hwmon

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing size validation in `rog_ryujin_raw_event` allows out-of-bounds memory reads.
- [High] The `status_report_request_lock` spinlock is ignored in `rog_ryujin_raw_event`, causing data races on completion states.
--

--- Patch [2]: [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support ---
commit b5b4a6af3fd216324c49f933284fb63343c21174
Author: Arie Miller <renari@arimil.com>

hwmon: (asus_rog_ryujin) Add ROG Ryujin III support

This commit adds model data, USB IDs, and report offsets for the ROG Ryujin
III Extreme and EVA Edition variants. It also skips controller commands
and hides unavailable controller channels for these devices.

Link: https://github.com/aleksamagicka/asus_rog_ryujin-hwmon/pull/9

> diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
> index b86b87e33615d..5bc60c6036de3 100644
> --- a/drivers/hwmon/asus_rog_ryujin.c
> +++ b/drivers/hwmon/asus_rog_ryujin.c
[ ... ]
> @@ -34,6 +36,14 @@ static const struct rog_ryujin_device_info rog_ryujin_ii_360_info = {
>  	.has_controller = true,
>  };
>  
> +static const struct rog_ryujin_device_info rog_ryujin_iii_info = {
> +	.temp_offset = 5,
> +	.pump_speed_offset = 7,
> +	.fan_speed_offset = 10,
> +	.duty_channel = 1,
> +	.has_controller = false,
> +};
> +

[Severity: High]
This is a pre-existing issue, but does rog_ryujin_raw_event() adequately
validate the report size before using these offsets?

If a malicious USB device provides a descriptor with a small max report size
but sends a valid-looking command prefix, the driver will read offsets up to
priv->info->fan_speed_offset without checking if the report size is
sufficient.

Could this cause an out-of-bounds read when accessing the payload fields?

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_raw_event() {
    ...
    priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
                          data[priv->info->temp_offset + 1] * 100;
    priv->speed_input[0] =
            get_unaligned_le16(data + priv->info->pump_speed_offset);
    ...
}

[Severity: High]
This is also a pre-existing issue, but is the status_report_request_lock
effective if it is ignored in rog_ryujin_raw_event()?

rog_ryujin_execute_cmd() acquires status_report_request_lock to protect
reinit_completion():

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_execute_cmd() {
    ...
    spin_lock_bh(&priv->status_report_request_lock);
    reinit_completion(status_completion);
    spin_unlock_bh(&priv->status_report_request_lock);
    ...
}

However, rog_ryujin_raw_event() ignores this lock when calling complete_all():

drivers/hwmon/asus_rog_ryujin.c:rog_ryujin_raw_event() {
    ...
    if (!completion_done(&priv->cooler_status_received))
        complete_all(&priv->cooler_status_received);
    ...
}

Could this lead to data races on the completion states and spurious sysfs
read/write timeouts when a USB raw event arrives concurrently with a
driver sysfs command?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260811233943.319729-1-renari@arimil.com?part=2

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data
  2026-08-11 23:39 ` [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data Arie Miller
  2026-08-11 23:51   ` sashiko-bot
@ 2026-08-12  2:00   ` Guenter Roeck
  1 sibling, 0 replies; 10+ messages in thread
From: Guenter Roeck @ 2026-08-12  2:00 UTC (permalink / raw)
  To: Arie Miller
  Cc: Aleksa Savic, Will Smith, Jonathan Corbet, Shuah Khan,
	linux-hwmon, linux-doc, linux-kernel

On 8/11/26 16:39, Arie Miller wrote:
> Handles an issue reported by Sashiko where an id could
> be missing driver_data.
> 
> Link: https://lore.kernel.org/r/5a817284-a9f4-48b2-9f0f-802c5dc6963c@roeck-us.net
> Assisted-by: Codex:gpt-5.6-sol sparse
> Signed-off-by: Arie Miller <renari@arimil.com>
> ---
>   drivers/hwmon/asus_rog_ryujin.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
> index 9b34c6e06bf7..702edb831394 100644
> --- a/drivers/hwmon/asus_rog_ryujin.c
> +++ b/drivers/hwmon/asus_rog_ryujin.c
> @@ -506,6 +506,9 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
>   	struct rog_ryujin_data *priv;
>   	int ret;
>   
> +	if (!id->driver_data)
> +		return -EINVAL;
> +

This will need to be part of the first patch of the series.

Guenter

>   	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
>   	if (!priv)
>   		return -ENOMEM;


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-08-12  2:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 23:39 [PATCH v2 0/4] hwmon: Add ASUS ROG Ryujin III support Arie Miller
2026-08-11 23:39 ` [PATCH v2 1/4] hwmon: (asus_rog_ryujin) Add per-device configuration Arie Miller
2026-08-11 23:49   ` sashiko-bot
2026-08-11 23:39 ` [PATCH v2 2/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III support Arie Miller
2026-08-11 23:52   ` sashiko-bot
2026-08-11 23:39 ` [PATCH v2 3/4] hwmon: (asus_rog_ryujin) Add ROG Ryujin III White Edition Arie Miller
2026-08-11 23:51   ` sashiko-bot
2026-08-11 23:39 ` [PATCH v2 4/4] hwmon: (asus_rog_ryujin) Handle missing driver data Arie Miller
2026-08-11 23:51   ` sashiko-bot
2026-08-12  2:00   ` Guenter Roeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.