The dropped-packet calculation uses a modulo against sequence_size (logical_maximum - logical_minimum + 1). When a HID descriptor declares a sequence field whose logical range spans all 32-bit values, sequence_size wraps to zero and the modulo triggers a divide exception. Replace the division-based calculation with a branch that computes the forward distance through the sequence range directly, as suggested by Jason Gerecke. This keeps the existing int types and avoids the divide-by-zero without any 64-bit arithmetic. Fixes: 359673ea3a20 ("HID: wacom: Support sequence numbers smaller than 16-bit") Cc: stable@vger.kernel.org Suggested-by: Jason Gerecke Signed-off-by: Aldo Ariel Panzardo --- Changes in v4: - Replace s64 arithmetic with a branch-based helper that computes the forward wrapped distance directly, as suggested by Jason Gerecke. Keeps sequence_number as int; no type changes needed. Changes in v3: - Replace raw s64 modulo with div64_s64()-based remainder to avoid __moddi3 link failure on 32-bit architectures (i386, arm32). Changes in v2: - Normalize logical_maximum/value as unsigned when logical_minimum >= 0, matching HID parser signedness. Store sequence state as s64. drivers/hid/wacom_wac.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 361738b..1d3ae94 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2426,6 +2426,13 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, } } +static int wacom_hid_wrapped_dist(int after, int before, int min, int max) +{ + if (after >= before) + return after - before; + return (max - before) + (after - min) + 1; +} + static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -2551,8 +2558,11 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field case WACOM_HID_WD_SEQUENCENUMBER: if (wacom_wac->hid_data.sequence_number != value && wacom_wac->hid_data.sequence_number >= 0) { - int sequence_size = field->logical_maximum - field->logical_minimum + 1; - int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size; + int drop_count = wacom_hid_wrapped_dist( + value, + wacom_wac->hid_data.sequence_number, + field->logical_minimum, + field->logical_maximum); hid_warn(hdev, "Dropped %d packets", drop_count); } wacom_wac->hid_data.sequence_number = value + 1; -- 2.53.0