Skip to contentSkip to conversation

HID: simplify snto32()

PATCH Applied Dmitry Torokhov 2 participants 3 messages Oct 3, 2024 – Oct 4, 2024

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 HID: simplify snto32()

snto32() does exactly what sign_extend32() does, but handles potentially malformed data coming from the device. Keep the checks, but then call sign_extend32() to perform the actual conversion.

---
 drivers/hid/hid-core.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/hid/hid-core.c +2 -9
index 00942d40fe08..5f62df91030d 100644
@@ -1313,9 +1313,7 @@ int hid_open_report(struct hid_device *device)
 EXPORT_SYMBOL_GPL(hid_open_report);
 
 /*
- * Convert a signed n-bit integer to signed 32-bit integer. Common
- * cases are done through the compiler, the screwed things has to be
- * done by hand.
+ * Convert a signed n-bit integer to signed 32-bit integer.
  */
 
 static s32 snto32(__u32 value, unsigned n)
@@ -1326,12 +1324,7 @@ static s32 snto32(__u32 value, unsigned n)
 	if (n > 32)
 		n = 32;
 
-	switch (n) {
-	case 8:  return ((__s8)value);
-	case 16: return ((__s16)value);
-	case 32: return ((__s32)value);
-	}
-	return value & (1 << (n - 1)) ? value | (~0U << n) : value;
+	return sign_extend32(value, n - 1);
 }
 
 s32 hid_snto32(__u32 value, unsigned n)
Signature · 1 line
2.47.0.rc0.187.ge670bccf7e-goog
#1 lore raw

PATCH 2/2 HID: stop exporting hid_snto32()

The only user of hid_snto32() is Logitech HID++ driver, which always calls hid_snto32() with valid size (constant, either 12 or 8) and therefore can simply use sign_extend32().

Make the switch and remove hid_snto32(). Move snto32() and s32ton() to avoid introducing forward declaration.

---
 drivers/hid/hid-core.c           | 62 +++++++++++++++-----------------
 drivers/hid/hid-logitech-hidpp.c |  6 ++--
 include/linux/hid.h              |  1 -
 3 files changed, 31 insertions(+), 38 deletions(-)
drivers/hid/hid-core.c +28 -34
index 5f62df91030d..f8c0a0316104 100644
@@ -45,6 +45,33 @@ static int hid_ignore_special_drivers = 0;
 module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
 MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver");
 
+/*
+ * Convert a signed n-bit integer to signed 32-bit integer.
+ */
+
+static s32 snto32(__u32 value, unsigned n)
+{
+	if (!value || !n)
+		return 0;
+
+	if (n > 32)
+		n = 32;
+
+	return sign_extend32(value, n - 1);
+}
+
+/*
+ * Convert a signed 32-bit integer to a signed n-bit integer.
+ */
+
+static u32 s32ton(__s32 value, unsigned n)
+{
+	s32 a = value >> (n - 1);
+	if (a && a != -1)
+		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
+	return value & ((1 << n) - 1);
+}
+
 /*
  * Register a new report for a device.
  */
@@ -425,7 +452,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
 		 * both this and the standard encoding. */
 		raw_value = item_sdata(item);
 		if (!(raw_value & 0xfffffff0))
-			parser->global.unit_exponent = hid_snto32(raw_value, 4);
+			parser->global.unit_exponent = snto32(raw_value, 4);
 		else
 			parser->global.unit_exponent = raw_value;
 		return 0;
@@ -1312,39 +1339,6 @@ int hid_open_report(struct hid_device *device)
 }
 EXPORT_SYMBOL_GPL(hid_open_report);
 
-/*
- * Convert a signed n-bit integer to signed 32-bit integer.
- */
-
-static s32 snto32(__u32 value, unsigned n)
-{
-	if (!value || !n)
-		return 0;
-
-	if (n > 32)
-		n = 32;
-
-	return sign_extend32(value, n - 1);
-}
-
-s32 hid_snto32(__u32 value, unsigned n)
-{
-	return snto32(value, n);
-}
-EXPORT_SYMBOL_GPL(hid_snto32);
-
-/*
- * Convert a signed 32-bit integer to a signed n-bit integer.
- */
-
-static u32 s32ton(__s32 value, unsigned n)
-{
-	s32 a = value >> (n - 1);
-	if (a && a != -1)
-		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
-	return value & ((1 << n) - 1);
-}
-
 /*
  * Extract/implement a data field from/to a little endian report (bit array).
  *
drivers/hid/hid-logitech-hidpp.c +3 -3
index 400d70e6dbe2..30ad42aac804 100644
@@ -3296,13 +3296,13 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
 					 120);
 		}
 
-		v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12);
+		v = sign_extend32(hid_field_extract(hdev, data + 3, 0, 12), 11);
 		input_report_rel(hidpp->input, REL_X, v);
 
-		v = hid_snto32(hid_field_extract(hdev, data+3, 12, 12), 12);
+		v = sign_extend32(hid_field_extract(hdev, data + 3, 12, 12), 11);
 		input_report_rel(hidpp->input, REL_Y, v);
 
-		v = hid_snto32(data[6], 8);
+		v = sign_extend32(data[6], 7);
 		if (v != 0)
 			hidpp_scroll_counter_handle_scroll(hidpp->input,
 					&hidpp->vertical_wheel_counter, v);
include/linux/hid.h +0 -1
index 1533c9dcd3a6..6dd0eb6cda68 100644
@@ -972,7 +972,6 @@ const struct hid_device_id *hid_match_device(struct hid_device *hdev,
 					     struct hid_driver *hdrv);
 bool hid_compare_device_paths(struct hid_device *hdev_a,
 			      struct hid_device *hdev_b, char separator);
-s32 hid_snto32(__u32 value, unsigned n);
 __u32 hid_field_extract(const struct hid_device *hid, __u8 *report,
 		     unsigned offset, unsigned n);
 
Signature · 1 line
2.47.0.rc0.187.ge670bccf7e-goog
maintainer Applied
#2 lore raw
In reply to Dmitry Torokhov
Quoted 5 lines · Dmitry Torokhov

snto32() does exactly what sign_extend32() does, but handles potentially malformed data coming from the device. Keep the checks, but then call sign_extend32() to perform the actual conversion.

Applied to hid/hid.git (for-6.13/core), thanks!

[1/2] HID: simplify snto32()

      https://git.kernel.org/hid/hid/c/ae9b956cb26c
[2/2] HID: stop exporting hid_snto32()
      https://git.kernel.org/hid/hid/c/c653ffc28340

Cheers,

Signature · 1 line
Benjamin Tissoires <[email protected]>