HID: simplify snto32()
Subsystems (3)
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
@@ -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
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
@@ -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
@@ -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
@@ -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
Quoted 5 lines · Dmitry Torokhov
snto32()does exactly whatsign_extend32()does, but handles potentially malformed data coming from the device. Keep the checks, but then callsign_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]>