git: fda9ac06aaf2 - main - bcm5974(4): fix endian conversion signedness bug

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Tue, 08 Mar 2022 12:52:10 UTC
The branch main has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=fda9ac06aaf2a3b862f485e9690e21edb17b5824

commit fda9ac06aaf2a3b862f485e9690e21edb17b5824
Author:     Greg V <greg@unrelenting.technology>
AuthorDate: 2022-03-08 12:51:06 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2022-03-08 12:51:06 +0000

    bcm5974(4): fix endian conversion signedness bug
    
    This fixes wrong coordinates resulting in weird behavior.
    
    Reviewed by:    wulf
    MFC with:       5aa839c9e2c373275091b8bf529c1311d0b84d76
    Differential revision:  https://reviews.freebsd.org/D34433
---
 sys/dev/hid/bcm5974.c | 66 +++++++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/sys/dev/hid/bcm5974.c b/sys/dev/hid/bcm5974.c
index d92c1c5c43b5..c940e022d2f1 100644
--- a/sys/dev/hid/bcm5974.c
+++ b/sys/dev/hid/bcm5974.c
@@ -154,22 +154,24 @@ struct tp_type_params {
 
 /* trackpad finger structure - little endian */
 struct tp_finger {
-	int16_t	origin;			/* zero when switching track finger */
-	int16_t	abs_x;			/* absolute x coodinate */
-	int16_t	abs_y;			/* absolute y coodinate */
-	int16_t	rel_x;			/* relative x coodinate */
-	int16_t	rel_y;			/* relative y coodinate */
-	int16_t	tool_major;		/* tool area, major axis */
-	int16_t	tool_minor;		/* tool area, minor axis */
-	int16_t	orientation;		/* 16384 when point, else 15 bit angle */
-	int16_t	touch_major;		/* touch area, major axis */
-	int16_t	touch_minor;		/* touch area, minor axis */
-	int16_t	unused[2];		/* zeros */
-	int16_t pressure;		/* pressure on forcetouch touchpad */
-	int16_t	multi;			/* one finger: varies, more fingers:
-				 	 * constant */
+	uint16_t	origin;		/* zero when switching track finger */
+	uint16_t	abs_x;		/* absolute x coodinate */
+	uint16_t	abs_y;		/* absolute y coodinate */
+	uint16_t	rel_x;		/* relative x coodinate */
+	uint16_t	rel_y;		/* relative y coodinate */
+	uint16_t	tool_major;	/* tool area, major axis */
+	uint16_t	tool_minor;	/* tool area, minor axis */
+	uint16_t	orientation;	/* 16384 when point, else 15 bit angle */
+	uint16_t	touch_major;	/* touch area, major axis */
+	uint16_t	touch_minor;	/* touch area, minor axis */
+	uint16_t	unused[2];	/* zeros */
+	uint16_t	pressure;	/* pressure on forcetouch touchpad */
+	uint16_t	multi;		/* one finger: varies, more fingers:
+					 * constant */
 } __packed;
 
+#define BCM5974_LE2H(x) ((int32_t)(int16_t)le16toh(x))
+
 /* trackpad finger data size, empirically at least ten fingers */
 #define	MAX_FINGERS		MAX_MT_SLOTS
 
@@ -694,26 +696,28 @@ bcm5974_intr(void *context, void *data, hid_size_t len)
 		DPRINTFN(BCM5974_LLEVEL_INFO,
 		    "[%d]ibt=%d, taps=%d, o=%4d, ax=%5d, ay=%5d, "
 		    "rx=%5d, ry=%5d, tlmaj=%4d, tlmin=%4d, ot=%4x, "
-		    "tchmaj=%4d, tchmin=%4d, presure=%4d, m=%4x\n",
-		    i, ibt, ntouch, le16toh(f->origin), le16toh(f->abs_x),
-		    le16toh(f->abs_y), le16toh(f->rel_x), le16toh(f->rel_y),
-		    le16toh(f->tool_major), le16toh(f->tool_minor),
-		    le16toh(f->orientation), le16toh(f->touch_major),
-		    le16toh(f->touch_minor), le16toh(f->pressure),
-		    le16toh(f->multi));
-
-		if (f->touch_major == 0)
+		    "tchmaj=%4d, tchmin=%4d, pressure=%4d, m=%4x\n",
+		    i, ibt, ntouch, BCM5974_LE2H(f->origin),
+		    BCM5974_LE2H(f->abs_x), BCM5974_LE2H(f->abs_y),
+		    BCM5974_LE2H(f->rel_x), BCM5974_LE2H(f->rel_y),
+		    BCM5974_LE2H(f->tool_major), BCM5974_LE2H(f->tool_minor),
+		    BCM5974_LE2H(f->orientation), BCM5974_LE2H(f->touch_major),
+		    BCM5974_LE2H(f->touch_minor), BCM5974_LE2H(f->pressure),
+		    BCM5974_LE2H(f->multi));
+
+		if (BCM5974_LE2H(f->touch_major) == 0)
 			continue;
 		slot_data = (union evdev_mt_slot) {
 			.id = slot,
-			.x = le16toh(f->abs_x),
-			.y = params->y.min + params->y.max - le16toh(f->abs_y),
-			.p = le16toh(f->pressure),
-			.maj = le16toh(f->touch_major) << 1,
-			.min = le16toh(f->touch_minor) << 1,
-			.w_maj = le16toh(f->tool_major) << 1,
-			.w_min = le16toh(f->tool_minor) << 1,
-			.ori = params->o.max - le16toh(f->orientation),
+			.x = BCM5974_LE2H(f->abs_x),
+			.y = params->y.min + params->y.max -
+			     BCM5974_LE2H(f->abs_y),
+			.p = BCM5974_LE2H(f->pressure),
+			.maj = BCM5974_LE2H(f->touch_major) << 1,
+			.min = BCM5974_LE2H(f->touch_minor) << 1,
+			.w_maj = BCM5974_LE2H(f->tool_major) << 1,
+			.w_min = BCM5974_LE2H(f->tool_minor) << 1,
+			.ori = params->o.max - BCM5974_LE2H(f->orientation),
 		};
 		evdev_mt_push_slot(sc->sc_evdev, slot, &slot_data);
 		slot++;