NetBSD Problem Report #45872
From khorben@defora.org Wed Jan 25 14:18:26 2012
Return-Path: <khorben@defora.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by www.NetBSD.org (Postfix) with ESMTP id AB60A63B91B
for <gnats-bugs@gnats.NetBSD.org>; Wed, 25 Jan 2012 14:18:26 +0000 (UTC)
Message-Id: <20120125125929.E0FDA1A464@syn.defora.rom>
Date: Wed, 25 Jan 2012 13:59:29 +0100 (CET)
From: Pierre Pronchery <khorben@defora.org>
Reply-To:
To: gnats-bugs@gnats.NetBSD.org
Subject: Issues and fixes for tpcalib (touchscreen calibration)
X-Send-Pr-Version: 3.95
>Number: 45872
>Category: kern
>Synopsis: Issues and fixes for tpcalib (touchscreen calibration)
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jan 25 14:20:00 +0000 2012
>Closed-Date: Thu Apr 24 11:46:30 +0000 2014
>Last-Modified: Thu Apr 24 11:46:30 +0000 2014
>Originator: Pierre Pronchery <khorben@defora.org>
>Release: NetBSD 5.99.60
>Organization:
>Environment:
System: NetBSD syn.defora.rom 5.99.60 NetBSD 5.99.60 (GENERIC) #43: Wed Jan 25 04:05:30 CET 2012 khorben@syn.defora.rom:/home/amd64/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
While working on the uts(4) driver, I had to calibrate the device for
proper mapping of screen coordinates. The driver itself uses the tpcalib
helper from the kernel, as also used in the ztp(4) and uep(4) drivers,
or on the hpcarm, hpcmips and hpcsh architectures apparently.
First, I have tried to add (partial) calibration support to the
wsconsctl user-land utility, for which patch is found below. While
apparently functional, this patch is not very helpful as it handles only
the range in which the values returned are desired. In practice, it is
sample collection which really helps in calibration (eg matching up to
WSMOUSE_CALIBCOORDS_MAX pairs of raw x/y versus desired x/y
coordinates). I think it would be helpful to commit anyway, maybe
without the warning about calibration support though, which would
otherwise affect 99% of users.
Then, I have been banging my head on the touchscreen (figuratively) in
order to get calibration to work. Turns out, there are some nasty bugs
in tpcalib_ioctl() with WSMOUSEIO_SCALIBCOORDS, when setting calibration
values through sample collection:
1. an invalid array access (and potential kernel crash?)
2. division-by-zero in the kernel (should it crash?)
3. a integer overflow (and invalid calibration)
I have been able to fix 1, but am still not sure about 2. I do not know
how to fix 3 at the moment, as I managed to calibrate the screen
properly without triggering it (by limiting my input to 4 samples).
1. Invalid array access
-----------------------
This bug is due to an invalid cast in sys/dev/wscons/mra.c, which
assumes the samples in struct wsmouse_calibcoord are of type long
instead of int. As a result, wrong values are used for the calibration;
worse, they may be read from uninitialized or invalid memory.
struct wsmouse_calibcoord {
int rawx, rawy; /* raw coordinate */
int x, y; /* translated coordinate */
} samples[WSMOUSE_CALIBCOORDS_MAX]; /* sample coordinates */
s = sizeof(struct wsmouse_calibcoord);
d = (const struct wsmouse_calibcoords *)data;
[...]
} else if (mra_Y_AX1_BX2_C(&d->samples[0].x, s,
&d->samples[0].rawx, s,
&d->samples[0].rawy, s,
d->samplelen, SCALE,
&sc->sc_ax, &sc->sc_bx, &sc->sc_cx)
and then:
int
mra_Y_AX1_BX2_C(const int *y, int ys,
const int *x1, int x1s, const int *x2, int x2s,
int n, int scale,
int *a, int *b, int *c)
{
[...]
#define AA(p, s, i) (*((const long *)(((const char *)(p)) + (s) * (i))))
#define X1(i) AA(x1, x1s, i)
#define X2(i) AA(x2, x2s, i)
#define Y(i) AA(y, ys, i)
for (i = 0; i < n; i++) {
X1a += X1(i);
Changing "const long *" to "const int *" in the AA macro is enough to
correct the behavior.
2. Division by zero
-------------------
The tpcalib_ioctl() function does not check if any sample was provided
in the first place, and will happily call the mra_Y_AX1_BX2_C() routine
anyway. As a result, nothing happens in the loop above, n is set to 0,
and this is called:
X1a /= n; X2a /= n; Ya /= n;
My experience in kernel programming (and NetBSD in particular) is not
sufficient to know if this would/should be a problem. In any case, my
test machine (amd64) did not crash, or print a warning either, although
I am sure that I have reached this code path multiple times.
3. Integer overflow
-------------------
My calibration attempts when supplying more than 4 samples have
consistently failed, inverting either of the X and Y axis, changing
their "speed", or otherwise triggering obviously wrong calibration. I am
absolutely sure that the values from my samples are correct; I have just
repeated the first ones (which work perfectly).
I therefore suspect integer overflows while processing the samples,
especially when I read this in the mra_Y_AX1_BX2_C() routine:
X1a += X1(i);
X2a += X2(i);
Ya += Y(i);
X1X1s += X1(i) * X1(i);
X2X2s += X2(i) * X2(i);
X1X2s += X1(i) * X2(i);
Does not look good to me, with up to 16 samples and coordinates
potentially as high as 2^31.
>How-To-Repeat:
Trying to calibrate a touchscreen with the tpcalib and wsmouse
frameworks.
>Fix:
Most essential:
Index: sys/dev/wscons/mra.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/mra.c,v
retrieving revision 1.4
diff -p -u -r1.4 mra.c
--- sys/dev/wscons/mra.c 9 Oct 2006 10:43:01 -0000 1.4
+++ sys/dev/wscons/mra.c 25 Jan 2012 12:50:53 -0000
@@ -54,13 +54,13 @@ mra_Y_AX1_BX2_C(const int *y, int ys,
int64_t S11, S22, S12;
int64_t SYY, S1Y, S2Y;
int64_t A, B, C, M;
-#define AA(p, s, i) (*((const long *)(((const char *)(p)) + (s) * (i))))
+#define AA(p, s, i) (*((const int *)(((const char *)(p)) + (s) * (i))))
#define X1(i) AA(x1, x1s, i)
#define X2(i) AA(x2, x2s, i)
#define Y(i) AA(y, ys, i)
/*
- * get avarage and sum
+ * get average and sum
*/
X1a = 0; X2a = 0; Ya = 0;
X1X1s = 0; X2X2s = 0; X1X2s = 0;
Would be welcome:
Index: sys/dev/usb/uts.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uts.c,v
retrieving revision 1.1
diff -p -u -r1.1 uts.c
--- sys/dev/usb/uts.c 17 Jan 2012 03:49:20 -0000 1.1
+++ sys/dev/usb/uts.c 25 Jan 2012 12:50:52 -0000
@@ -142,6 +142,7 @@ uts_attach(device_t parent, device_t sel
struct hid_item item;
aprint_naive("\n");
+ aprint_normal("\n");
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = uts_intr;
@@ -226,8 +227,6 @@ uts_attach(device_t parent, device_t sel
/* calibrate the touchscreen */
memset(&sc->sc_calibcoords, 0, sizeof(sc->sc_calibcoords));
- sc->sc_calibcoords.maxx = 4095;
- sc->sc_calibcoords.maxy = 4095;
sc->sc_calibcoords.samplelen = WSMOUSE_CALIBCOORDS_RESET;
d = hid_start_parse(desc, size, hid_input);
while (hid_get_item(d, &item)) {
@@ -244,6 +243,9 @@ uts_attach(device_t parent, device_t sel
sc->sc_calibcoords.maxy = item.logical_maximum;
}
}
+ if (sc->sc_calibcoords.maxx != 0
+ && sc->sc_calibcoords.maxy != 0)
+ sc->sc_calibcoords.samplelen = 0;
hid_end_parse(d);
tpcalib_init(&sc->sc_tpcalib);
To be considered:
Index: sys/dev/wscons/tpcalib.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/tpcalib.c,v
retrieving revision 1.11
diff -p -u -r1.11 tpcalib.c
--- sys/dev/wscons/tpcalib.c 4 Mar 2007 06:02:51 -0000 1.11
+++ sys/dev/wscons/tpcalib.c 25 Jan 2012 12:50:53 -0000
@@ -65,6 +65,8 @@ tpcalib_init(struct tpcalib_softc *sc)
void
tpcalib_reset(struct tpcalib_softc *sc)
{
+ memset(sc, 0, sizeof(struct tpcalib_softc));
+
/* This indicate 'raw mode'. No translation will be done. */
sc->sc_saved.samplelen = WSMOUSE_CALIBCOORDS_RESET;
}
@@ -99,10 +101,20 @@ tpcalib_ioctl(struct tpcalib_softc *sc,
case WSMOUSEIO_SCALIBCOORDS:
s = sizeof(struct wsmouse_calibcoord);
d = (const struct wsmouse_calibcoords *)data;
- if (d->samplelen == WSMOUSE_CALIBCOORDS_RESET) {
+ if (d->samplelen == WSMOUSE_CALIBCOORDS_RESET ||
+ d->samplelen < 0 ||
+ d->samplelen >= WSMOUSE_CALIBCOORDS_MAX) {
tpcalib_reset(sc);
- } else
- if (mra_Y_AX1_BX2_C(&d->samples[0].x, s,
+ break;
+ }
+ if (d->samplelen == 0) {
+ sc->sc_ax = SCALE;
+ sc->sc_bx = 0;
+ sc->sc_cx = 0;
+ sc->sc_ay = 0;
+ sc->sc_by = SCALE;
+ sc->sc_cy = 0;
+ } else if (mra_Y_AX1_BX2_C(&d->samples[0].x, s,
&d->samples[0].rawx, s,
&d->samples[0].rawy, s,
d->samplelen, SCALE,
@@ -112,24 +124,23 @@ tpcalib_ioctl(struct tpcalib_softc *sc,
&d->samples[0].rawy, s,
d->samplelen, SCALE,
&sc->sc_ay, &sc->sc_by, &sc->sc_cy)) {
- printf("tpcalib: MRA error");
- tpcalib_reset(sc);
+ printf("tpcalib: MRA error\n");
+ tpcalib_reset(sc);
- return (EINVAL);
- } else {
- sc->sc_minx = d->minx;
- sc->sc_maxx = d->maxx;
- sc->sc_miny = d->miny;
- sc->sc_maxy = d->maxy;
- sc->sc_saved = *d;
- DPRINTF(("tpcalib: x=%d~%d y=%d~%d\n",
- sc->sc_minx, sc->sc_maxx,
- sc->sc_miny, sc->sc_maxy));
- DPRINTF(("tpcalib: Ax=%d Bx=%d Cx=%d\n",
- sc->sc_ax, sc->sc_bx, sc->sc_cx));
- DPRINTF(("tpcalib: Ay=%d By=%d Cy=%d\n",
- sc->sc_ay, sc->sc_by, sc->sc_cy));
- }
+ return (EINVAL);
+ }
+ sc->sc_minx = d->minx;
+ sc->sc_maxx = d->maxx;
+ sc->sc_miny = d->miny;
+ sc->sc_maxy = d->maxy;
+ sc->sc_saved = *d;
+ DPRINTF(("tpcalib: x=%d~%d y=%d~%d\n",
+ sc->sc_minx, sc->sc_maxx,
+ sc->sc_miny, sc->sc_maxy));
+ DPRINTF(("tpcalib: Ax=%d Bx=%d Cx=%d\n",
+ sc->sc_ax, sc->sc_bx, sc->sc_cx));
+ DPRINTF(("tpcalib: Ay=%d By=%d Cy=%d\n",
+ sc->sc_ay, sc->sc_by, sc->sc_cy));
break;
case WSMOUSEIO_GCALIBCOORDS:
As well as:
Index: sbin/wsconsctl/mouse.c
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/mouse.c,v
retrieving revision 1.8
diff -p -u -r1.8 mouse.c
--- sbin/wsconsctl/mouse.c 28 Apr 2008 20:23:09 -0000 1.8
+++ sbin/wsconsctl/mouse.c 25 Jan 2012 12:50:34 -0000
@@ -45,8 +45,12 @@
static int mstype;
static int resolution;
static int samplerate;
+static struct wsmouse_calibcoords calibration;
static struct wsmouse_repeat repeat;
+static void mouse_get_calibration(int);
+static void mouse_put_calibration(int);
+
static void mouse_get_repeat(int);
static void mouse_put_repeat(int);
@@ -54,6 +58,14 @@ struct field mouse_field_tab[] = {
{ "resolution", &resolution, FMT_UINT, FLG_WRONLY },
{ "samplerate", &samplerate, FMT_UINT, FLG_WRONLY },
{ "type", &mstype, FMT_MSTYPE, FLG_RDONLY },
+ { "calibration.minx", &calibration.minx,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.miny", &calibration.miny,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.maxx", &calibration.maxx,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.maxy", &calibration.maxy,
+ FMT_INT, FLG_MODIFY },
{ "repeat.buttons", &repeat.wr_buttons,
FMT_BITFIELD, FLG_MODIFY },
{ "repeat.delay.first", &repeat.wr_delay_first,
@@ -75,6 +87,12 @@ mouse_get_values(int fd)
if (ioctl(fd, WSMOUSEIO_GTYPE, &mstype) < 0)
err(EXIT_FAILURE, "WSMOUSEIO_GTYPE");
+ if (field_by_value(&calibration.minx)->flags & FLG_GET ||
+ field_by_value(&calibration.miny)->flags & FLG_GET ||
+ field_by_value(&calibration.maxx)->flags & FLG_GET ||
+ field_by_value(&calibration.maxy)->flags & FLG_GET)
+ mouse_get_calibration(fd);
+
if (field_by_value(&repeat.wr_buttons)->flags & FLG_GET ||
field_by_value(&repeat.wr_delay_first)->flags & FLG_GET ||
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_GET ||
@@ -83,6 +101,31 @@ mouse_get_values(int fd)
}
static void
+mouse_get_calibration(int fd)
+{
+ struct wsmouse_calibcoords tmp;
+
+ if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) == -1)
+ {
+ warn("WSMOUSEIO_GCALIBCOORDS");
+ field_disable_by_value(&calibration.minx);
+ field_disable_by_value(&calibration.miny);
+ field_disable_by_value(&calibration.maxx);
+ field_disable_by_value(&calibration.maxy);
+ return;
+ }
+
+ if (field_by_value(&calibration.minx)->flags & FLG_GET)
+ calibration.minx = tmp.minx;
+ if (field_by_value(&calibration.miny)->flags & FLG_GET)
+ calibration.miny = tmp.miny;
+ if (field_by_value(&calibration.maxx)->flags & FLG_GET)
+ calibration.maxx = tmp.maxx;
+ if (field_by_value(&calibration.maxy)->flags & FLG_GET)
+ calibration.maxy = tmp.maxy;
+}
+
+static void
mouse_get_repeat(int fd)
{
struct wsmouse_repeat tmp;
@@ -119,6 +162,12 @@ mouse_put_values(int fd)
pr_field(field_by_value(&samplerate), " -> ");
}
+ if (field_by_value(&calibration.minx)->flags & FLG_SET ||
+ field_by_value(&calibration.miny)->flags & FLG_SET ||
+ field_by_value(&calibration.maxx)->flags & FLG_SET ||
+ field_by_value(&calibration.maxy)->flags & FLG_SET)
+ mouse_put_calibration(fd);
+
if (field_by_value(&repeat.wr_buttons)->flags & FLG_SET ||
field_by_value(&repeat.wr_delay_first)->flags & FLG_SET ||
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET ||
@@ -127,6 +176,40 @@ mouse_put_values(int fd)
}
static void
+mouse_put_calibration(int fd)
+{
+ struct wsmouse_calibcoords tmp;
+
+ /* Fetch current values into the temporary structure. */
+ if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) == -1)
+ err(EXIT_FAILURE, "WSMOUSEIO_GCALIBCOORDS");
+
+ /* Overwrite the desired values in the temporary structure. */
+ if (field_by_value(&calibration.minx)->flags & FLG_SET)
+ tmp.minx = calibration.minx;
+ if (field_by_value(&calibration.miny)->flags & FLG_SET)
+ tmp.miny = calibration.miny;
+ if (field_by_value(&calibration.maxx)->flags & FLG_SET)
+ tmp.maxx = calibration.maxx;
+ if (field_by_value(&calibration.maxy)->flags & FLG_SET)
+ tmp.maxy = calibration.maxy;
+
+ /* Set new values for calibrating events. */
+ if (ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &tmp) == -1)
+ err(EXIT_FAILURE, "WSMOUSEIO_SCALIBCOORDS");
+
+ /* Now print what changed. */
+ if (field_by_value(&calibration.minx)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.minx), " -> ");
+ if (field_by_value(&calibration.miny)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.miny), " -> ");
+ if (field_by_value(&calibration.maxx)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.maxx), " -> ");
+ if (field_by_value(&calibration.maxy)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.maxy), " -> ");
+}
+
+static void
mouse_put_repeat(int fd)
{
struct wsmouse_repeat tmp;
Index: sbin/wsconsctl/util.c
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/util.c,v
retrieving revision 1.30
diff -p -u -r1.30 util.c
--- sbin/wsconsctl/util.c 15 Dec 2011 14:25:12 -0000 1.30
+++ sbin/wsconsctl/util.c 25 Jan 2012 12:50:34 -0000
@@ -263,6 +263,9 @@ pr_field(struct field *f, const char *se
case FMT_BITFIELD:
pr_bitfield(*((unsigned int *) f->valp));
break;
+ case FMT_INT:
+ (void)printf("%d", *((int *) f->valp));
+ break;
case FMT_KBDTYPE:
p = int2name(*((unsigned int *) f->valp), 1,
kbtype_tab, TABLEN(kbtype_tab));
@@ -368,6 +371,14 @@ rd_field(struct field *f, char *val, int
case FMT_BITFIELD:
*((unsigned int *) f->valp) = rd_bitfield(val);
break;
+ case FMT_INT:
+ if (sscanf(val, "%d", &i) != 1)
+ errx(EXIT_FAILURE, "%s: not a number", val);
+ if (merge)
+ *((int *) f->valp) += i;
+ else
+ *((int *) f->valp) = i;
+ break;
case FMT_KBDENC:
p = strchr(val, '.');
if (p != NULL)
Index: sbin/wsconsctl/wsconsctl.h
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/wsconsctl.h,v
retrieving revision 1.11
diff -p -u -r1.11 wsconsctl.h
--- sbin/wsconsctl/wsconsctl.h 27 Aug 2011 19:01:34 -0000 1.11
+++ sbin/wsconsctl/wsconsctl.h 25 Jan 2012 12:50:34 -0000
@@ -55,6 +55,7 @@ struct field {
#define FMT_UINT 1 /* unsigned integer */
#define FMT_STRING 2 /* zero terminated string */
#define FMT_BITFIELD 3 /* bit field */
+#define FMT_INT 4 /* signed integer */
#define FMT_KBDTYPE 101 /* keyboard type */
#define FMT_MSTYPE 102 /* mouse type */
#define FMT_DPYTYPE 103 /* display type */
And for the record, the code I used to submit samples:
=== BEGIN PASTE ===
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dev/wscons/wsconsio.h>
static int _error(char const * message, int ret)
{
fputs("calib: ", stderr);
perror(message);
return ret;
}
static int _usage(void)
{
fputs("Usage: calib\n", stderr);
return 1;
}
int main(int argc, char * argv[])
{
int o;
int fd;
struct wsmouse_calibcoords calib;
while((o = getopt(argc, argv, "")) != -1)
switch(o)
{
default:
return _usage();
}
if(optind != argc)
return _usage();
if((fd = open("/dev/wsmouse", O_WRONLY)) < 0)
fd = open("/dev/wsmouse", O_RDONLY);
if(fd < 0)
return _error("/dev/wsmouse", 2);
memset(&calib, 0, sizeof(calib));
if(ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &calib) != 0)
{
close(fd);
return _error("WSMOUSEIO_GCALIBCOORDS", 2);
}
printf("x=(%d,%d) y=(%d,%d) %d samples\n", calib.minx, calib.maxx,
calib.miny, calib.maxy, calib.samplelen);
#if 0
calib.minx = 0;
calib.miny = 0;
calib.maxx = 4095;
calib.maxy = 4095;
#endif
calib.samplelen = 4;
memset(&calib.samples, 0, sizeof(calib.samples));
/* maximum values likely */
calib.samples[0].rawx = 4095;
calib.samples[0].rawy = 4095;
calib.samples[0].x = 1023;
calib.samples[0].y = 599;
/* top left */
calib.samples[1].rawx = 256;
calib.samples[1].rawy = 328;
calib.samples[1].x = 64;
calib.samples[1].y = 48;
/* top right */
calib.samples[2].rawx = 3840;
calib.samples[2].rawy = 328;
calib.samples[2].x = 960;
calib.samples[2].y = 48;
/* bottom right */
calib.samples[3].rawx = 3840;
calib.samples[3].rawy = 3768;
calib.samples[3].x = 960;
calib.samples[3].y = 552;
#if 0 /* FIXME disabled as it seems to overflow inside the kernel */
/* bottom left */
calib.samples[4].rawx = 256;
calib.samples[4].rawy = 3768;
calib.samples[4].x = 64;
calib.samples[4].y = 552;
#endif
if(ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &calib) != 0)
{
close(fd);
return _error("WSMOUSEIO_SCALIBCOORDS", 2);
}
if(close(fd) != 0)
return _error("/dev/wsmouse", 2);
return 0;
}
=== END PASTE ===
Would either of the addition of uts(4) and these fixes be worth an entry
in doc/CHANGES?
Cheers!
>Release-Note:
>Audit-Trail:
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/45872: Issues and fixes for tpcalib (touchscreen calibration)
[was: kernel build failure: uts]
Date: Thu, 09 Feb 2012 18:07:54 +0100
On 07/02/2012 22:19, Thomas Klausner wrote:
> # link YT/netbsd
> /archive/build/tools/bin/x86_64--netbsd-ld -Map netbsd.map --cref -T /archive/cvs/src/sys/arch/amd64/conf/kern.ldscript -Ttext 0xffffffff80100000 -e start -z max-page-size=0x100000 -X -o netbsd ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
> uts.o: In function `uts_attach': [...]
> *** [netbsd] Error code 1
>
> It's a stripped down GENERIC, but uts should pull in its dependencies...
You are right, and I believe the following should therefore be changed
in sys/dev/usb/files.usb, around line 91:
# Touchscreens
-device uts: hid, wsmousedev
+device uts: hid, wsmousedev, tpcalib
attach uts at uhidbus
Sorry for the inconvenience.
HTH,
--
khorben
From: "Thomas Klausner" <wiz@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sys/dev/usb
Date: Mon, 13 Feb 2012 14:36:40 +0000
Module Name: src
Committed By: wiz
Date: Mon Feb 13 14:36:39 UTC 2012
Modified Files:
src/sys/dev/usb: files.usb
Log Message:
Add missing dependency for uts.
From Pierre Pronchery <khorben@defora.org> in PR 45872.
To generate a diff of this commit:
cvs rdiff -u -r1.119 -r1.120 src/sys/dev/usb/files.usb
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Thomas Klausner <wiz@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/45872: Issues and fixes for tpcalib (touchscreen
calibration) [was: kernel build failure: uts]
Date: Mon, 13 Feb 2012 15:37:13 +0100
On Thu, Feb 09, 2012 at 05:10:05PM +0000, Pierre Pronchery wrote:
> You are right, and I believe the following should therefore be changed
> in sys/dev/usb/files.usb, around line 91:
>
> # Touchscreens
> -device uts: hid, wsmousedev
> +device uts: hid, wsmousedev, tpcalib
> attach uts at uhidbus
>
> Sorry for the inconvenience.
Yes, that works, and I've committed it. Thank you!
Thomas
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/45872: Issues and fixes for tpcalib (touchscreen calibration)
Date: Sat, 18 Feb 2012 13:38:48 -0500
This is a multi-part message in MIME format.
--------------070005020708030603080700
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Hi all,
I have made additional modifications to sbin/wsconstl to fully support
calibration; with them I can calibrate my touchscreen with wsconsctl
directly.
As an example, on that same Lenovo IdeaPad S10-3t at a screen resolution
of 1024x600:
=== BEGIN PASTE ===
#!/bin/sh
wsconsctl -mw calibration.maxx=4096
wsconsctl -mw calibration.maxy=4096
wsconsctl -mw
calibration.samples=4095,4095,1023,599:256,328,64,48:3840,328,960,48:3840,3768,960,552
=== END PASTE ===
This change also obsoletes the manual pages for at least uts(4) and
uep(4), which both mention that they do not support calibration. It may
also be true of ztp(4) (in the zaurus port).
HTH!
--
khorben
--------------070005020708030603080700
Content-Type: text/plain;
name="wsconsctl.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="wsconsctl.diff"
Index: mouse.c
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/mouse.c,v
retrieving revision 1.8
diff -p -u -r1.8 mouse.c
--- mouse.c 28 Apr 2008 20:23:09 -0000 1.8
+++ mouse.c 18 Feb 2012 18:32:15 -0000
@@ -45,8 +45,13 @@
static int mstype;
static int resolution;
static int samplerate;
+static struct wsmouse_calibcoords calibration;
+static char * calibration_samples;
static struct wsmouse_repeat repeat;
+static void mouse_get_calibration(int);
+static void mouse_put_calibration(int);
+
static void mouse_get_repeat(int);
static void mouse_put_repeat(int);
@@ -54,6 +59,16 @@ struct field mouse_field_tab[] = {
{ "resolution", &resolution, FMT_UINT, FLG_WRONLY },
{ "samplerate", &samplerate, FMT_UINT, FLG_WRONLY },
{ "type", &mstype, FMT_MSTYPE, FLG_RDONLY },
+ { "calibration.minx", &calibration.minx,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.miny", &calibration.miny,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.maxx", &calibration.maxx,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.maxy", &calibration.maxy,
+ FMT_INT, FLG_MODIFY },
+ { "calibration.samples", &calibration_samples,
+ FMT_STRING, FLG_MODIFY },
{ "repeat.buttons", &repeat.wr_buttons,
FMT_BITFIELD, FLG_MODIFY },
{ "repeat.delay.first", &repeat.wr_delay_first,
@@ -75,6 +90,13 @@ mouse_get_values(int fd)
if (ioctl(fd, WSMOUSEIO_GTYPE, &mstype) < 0)
err(EXIT_FAILURE, "WSMOUSEIO_GTYPE");
+ if (field_by_value(&calibration.minx)->flags & FLG_GET ||
+ field_by_value(&calibration.miny)->flags & FLG_GET ||
+ field_by_value(&calibration.maxx)->flags & FLG_GET ||
+ field_by_value(&calibration.maxy)->flags & FLG_GET ||
+ field_by_value(&calibration_samples)->flags & FLG_GET)
+ mouse_get_calibration(fd);
+
if (field_by_value(&repeat.wr_buttons)->flags & FLG_GET ||
field_by_value(&repeat.wr_delay_first)->flags & FLG_GET ||
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_GET ||
@@ -83,6 +105,56 @@ mouse_get_values(int fd)
}
static void
+mouse_get_calibration(int fd)
+{
+ struct wsmouse_calibcoords tmp;
+ char * samples = NULL;
+ char buf[48];
+ int i;
+
+ if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) == -1)
+ {
+ warn("WSMOUSEIO_GCALIBCOORDS");
+ field_disable_by_value(&calibration.minx);
+ field_disable_by_value(&calibration.miny);
+ field_disable_by_value(&calibration.maxx);
+ field_disable_by_value(&calibration.maxy);
+ field_disable_by_value(&calibration_samples);
+ return;
+ }
+
+ if (field_by_value(&calibration.minx)->flags & FLG_GET)
+ calibration.minx = tmp.minx;
+ if (field_by_value(&calibration.miny)->flags & FLG_GET)
+ calibration.miny = tmp.miny;
+ if (field_by_value(&calibration.maxx)->flags & FLG_GET)
+ calibration.maxx = tmp.maxx;
+ if (field_by_value(&calibration.maxy)->flags & FLG_GET)
+ calibration.maxy = tmp.maxy;
+ if (field_by_value(&calibration_samples)->flags & FLG_GET)
+ {
+ calibration_samples = strdup("");
+ if(tmp.samplelen >= 0 && (samples = malloc(tmp.samplelen
+ * sizeof(buf))) != NULL)
+ {
+ samples[0] = '\0';
+ for (i = 0; i < tmp.samplelen; i++)
+ {
+ snprintf(buf, sizeof(buf), "%s%d,%d,%d,%d",
+ (i == 0) ? "" : ":",
+ tmp.samples[i].rawx,
+ tmp.samples[i].rawy,
+ tmp.samples[i].x,
+ tmp.samples[i].y);
+ strcat(samples, buf);
+ }
+ free(calibration_samples);
+ calibration_samples = samples;
+ }
+ }
+}
+
+static void
mouse_get_repeat(int fd)
{
struct wsmouse_repeat tmp;
@@ -119,6 +191,13 @@ mouse_put_values(int fd)
pr_field(field_by_value(&samplerate), " -> ");
}
+ if (field_by_value(&calibration.minx)->flags & FLG_SET ||
+ field_by_value(&calibration.miny)->flags & FLG_SET ||
+ field_by_value(&calibration.maxx)->flags & FLG_SET ||
+ field_by_value(&calibration.maxy)->flags & FLG_SET ||
+ field_by_value(&calibration_samples)->flags & FLG_SET)
+ mouse_put_calibration(fd);
+
if (field_by_value(&repeat.wr_buttons)->flags & FLG_SET ||
field_by_value(&repeat.wr_delay_first)->flags & FLG_SET ||
field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET ||
@@ -127,6 +206,69 @@ mouse_put_values(int fd)
}
static void
+mouse_put_calibration(int fd)
+{
+ struct wsmouse_calibcoords tmp;
+ int i;
+ char const * p;
+ char * q;
+
+ /* Fetch current values into the temporary structure. */
+ if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) == -1)
+ err(EXIT_FAILURE, "WSMOUSEIO_GCALIBCOORDS");
+
+ /* Overwrite the desired values in the temporary structure. */
+ if (field_by_value(&calibration.minx)->flags & FLG_SET)
+ tmp.minx = calibration.minx;
+ if (field_by_value(&calibration.miny)->flags & FLG_SET)
+ tmp.miny = calibration.miny;
+ if (field_by_value(&calibration.maxx)->flags & FLG_SET)
+ tmp.maxx = calibration.maxx;
+ if (field_by_value(&calibration.maxy)->flags & FLG_SET)
+ tmp.maxy = calibration.maxy;
+ if (field_by_value(&calibration_samples)->flags & FLG_SET)
+ {
+ p = calibration_samples;
+ for(i = 0; p[0] != '\0' && i < WSMOUSE_CALIBCOORDS_MAX; i++)
+ {
+ tmp.samples[i].rawx = strtol(p, &q, 0);
+ if(*q != ',')
+ break;
+ p = q + 1;
+ tmp.samples[i].rawy = strtol(p, &q, 0);
+ if(*q != ',')
+ break;
+ p = q + 1;
+ tmp.samples[i].x = strtol(p, &q, 0);
+ if(*q != ',')
+ break;
+ p = q + 1;
+ tmp.samples[i].y = strtol(p, &q, 0);
+ p = q + 1;
+ if(*q != '\0' && *q != ':')
+ break;
+ }
+ tmp.samplelen = i;
+ }
+
+ /* Set new values for calibrating events. */
+ if (ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &tmp) == -1)
+ err(EXIT_FAILURE, "WSMOUSEIO_SCALIBCOORDS");
+
+ /* Now print what changed. */
+ if (field_by_value(&calibration.minx)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.minx), " -> ");
+ if (field_by_value(&calibration.miny)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.miny), " -> ");
+ if (field_by_value(&calibration.maxx)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.maxx), " -> ");
+ if (field_by_value(&calibration.maxy)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration.maxy), " -> ");
+ if (field_by_value(&calibration_samples)->flags & FLG_SET)
+ pr_field(field_by_value(&calibration_samples), " -> ");
+}
+
+static void
mouse_put_repeat(int fd)
{
struct wsmouse_repeat tmp;
Index: util.c
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/util.c,v
retrieving revision 1.30
diff -p -u -r1.30 util.c
--- util.c 15 Dec 2011 14:25:12 -0000 1.30
+++ util.c 18 Feb 2012 18:32:15 -0000
@@ -263,6 +263,9 @@ pr_field(struct field *f, const char *se
case FMT_BITFIELD:
pr_bitfield(*((unsigned int *) f->valp));
break;
+ case FMT_INT:
+ (void)printf("%d", *((int *) f->valp));
+ break;
case FMT_KBDTYPE:
p = int2name(*((unsigned int *) f->valp), 1,
kbtype_tab, TABLEN(kbtype_tab));
@@ -368,6 +371,14 @@ rd_field(struct field *f, char *val, int
case FMT_BITFIELD:
*((unsigned int *) f->valp) = rd_bitfield(val);
break;
+ case FMT_INT:
+ if (sscanf(val, "%d", &i) != 1)
+ errx(EXIT_FAILURE, "%s: not a number", val);
+ if (merge)
+ *((int *) f->valp) += i;
+ else
+ *((int *) f->valp) = i;
+ break;
case FMT_KBDENC:
p = strchr(val, '.');
if (p != NULL)
Index: wsconsctl.h
===================================================================
RCS file: /cvsroot/src/sbin/wsconsctl/wsconsctl.h,v
retrieving revision 1.11
diff -p -u -r1.11 wsconsctl.h
--- wsconsctl.h 27 Aug 2011 19:01:34 -0000 1.11
+++ wsconsctl.h 18 Feb 2012 18:32:15 -0000
@@ -55,6 +55,7 @@ struct field {
#define FMT_UINT 1 /* unsigned integer */
#define FMT_STRING 2 /* zero terminated string */
#define FMT_BITFIELD 3 /* bit field */
+#define FMT_INT 4 /* signed integer */
#define FMT_KBDTYPE 101 /* keyboard type */
#define FMT_MSTYPE 102 /* mouse type */
#define FMT_DPYTYPE 103 /* display type */
--------------070005020708030603080700--
From: "Pierre Pronchery" <khorben@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sbin/wsconsctl
Date: Mon, 24 Dec 2012 01:20:13 +0000
Module Name: src
Committed By: khorben
Date: Mon Dec 24 01:20:12 UTC 2012
Modified Files:
src/sbin/wsconsctl: util.c
Log Message:
Added a field type for signed integers. This is required when handling
touchscreen calibration values, which is about to be implemented in
wsconsctl (see PR kern/45872).
Reviewed by uwe@ (thank you!)
To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sbin/wsconsctl/util.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Pierre Pronchery" <khorben@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sbin/wsconsctl
Date: Mon, 24 Dec 2012 01:20:45 +0000
Module Name: src
Committed By: khorben
Date: Mon Dec 24 01:20:45 UTC 2012
Modified Files:
src/sbin/wsconsctl: wsconsctl.h
Log Message:
Added a field type for signed integers. This is required when handling
touchscreen calibration values, which is about to be implemented in
wsconsctl (see PR kern/45872).
Reviewed by uwe@ (thank you!)
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sbin/wsconsctl/wsconsctl.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Pierre Pronchery" <khorben@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sbin/wsconsctl
Date: Mon, 24 Dec 2012 01:27:23 +0000
Module Name: src
Committed By: khorben
Date: Mon Dec 24 01:27:23 UTC 2012
Modified Files:
src/sbin/wsconsctl: mouse.c
Log Message:
Added read-only support for touchscreen calibration (see PR kern/45872).
Tested with the uts(4) driver, as well as with mice without calibration
support.
Reviewed by uwe@ (thank you!)
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sbin/wsconsctl/mouse.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Pierre Pronchery" <khorben@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sbin/wsconsctl
Date: Mon, 24 Dec 2012 01:29:20 +0000
Module Name: src
Committed By: khorben
Date: Mon Dec 24 01:29:20 UTC 2012
Modified Files:
src/sbin/wsconsctl: mouse.c
Log Message:
Added complete support for touchscreen calibration (see PR kern/45872).
Tested with the uts(4) driver, as well as with mice without calibration
support.
Reviewed by uwe@ (thank you!)
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sbin/wsconsctl/mouse.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Jeff Rizzo" <riz@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: [netbsd-6] src/sbin/wsconsctl
Date: Mon, 11 Feb 2013 21:36:30 +0000
Module Name: src
Committed By: riz
Date: Mon Feb 11 21:36:30 UTC 2013
Modified Files:
src/sbin/wsconsctl [netbsd-6]: mouse.c util.c wsconsctl.h
Log Message:
Pull up following revision(s) (requested by khorben in ticket #814):
sbin/wsconsctl/wsconsctl.h: revision 1.12
sbin/wsconsctl/mouse.c: revision 1.9
sbin/wsconsctl/mouse.c: revision 1.10
sbin/wsconsctl/util.c: revision 1.31
Added a field type for signed integers. This is required when handling
touchscreen calibration values, which is about to be implemented in
wsconsctl (see PR kern/45872).
Reviewed by uwe@ (thank you!)
Added a field type for signed integers. This is required when handling
touchscreen calibration values, which is about to be implemented in
wsconsctl (see PR kern/45872).
Reviewed by uwe@ (thank you!)
Added read-only support for touchscreen calibration (see PR kern/45872).
Tested with the uts(4) driver, as well as with mice without calibration
support.
Reviewed by uwe@ (thank you!)
Added complete support for touchscreen calibration (see PR kern/45872).
Tested with the uts(4) driver, as well as with mice without calibration
support.
Reviewed by uwe@ (thank you!)
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.8.22.1 src/sbin/wsconsctl/mouse.c
cvs rdiff -u -r1.30 -r1.30.2.1 src/sbin/wsconsctl/util.c
cvs rdiff -u -r1.11 -r1.11.4.1 src/sbin/wsconsctl/wsconsctl.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 07 Oct 2013 05:49:10 +0000
State-Changed-Why:
Is this finished? Most of it seems to have been committed and pulled up.
From: "Pierre Pronchery" <khorben@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: src/sys/dev/wscons
Date: Fri, 14 Mar 2014 05:03:19 +0000
Module Name: src
Committed By: khorben
Date: Fri Mar 14 05:03:19 UTC 2014
Modified Files:
src/sys/dev/wscons: mra.c
Log Message:
Fixed wrong cast and invalid array access in the calibration framework, as
documented in PR kern/45872. The AA() macro accessed sample coordinates as
long integers, whereas they are really stored as signed integers.
Fixes calibration on my Wetab device.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/wscons/mra.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "SAITOH Masanobu" <msaitoh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: [netbsd-6] src/sys/dev/wscons
Date: Fri, 11 Apr 2014 08:38:07 +0000
Module Name: src
Committed By: msaitoh
Date: Fri Apr 11 08:38:07 UTC 2014
Modified Files:
src/sys/dev/wscons [netbsd-6]: mra.c
Log Message:
Pull up following revision(s) (requested by khorben in ticket #1037):
sys/dev/wscons/mra.c 1.6
Fixed wrong cast and invalid array access in the calibration framework,
as documented in PR kern/45872. The AA() macro accessed sample
coordinates as long integers, whereas they are really stored as signed
integers.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.4.94.1 src/sys/dev/wscons/mra.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "SAITOH Masanobu" <msaitoh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/45872 CVS commit: [netbsd-5] src/sys/dev/wscons
Date: Wed, 16 Apr 2014 08:10:25 +0000
Module Name: src
Committed By: msaitoh
Date: Wed Apr 16 08:10:25 UTC 2014
Modified Files:
src/sys/dev/wscons [netbsd-5]: mra.c
Log Message:
Pull up following revision(s) (requested by khorben in ticket #1900):
sys/dev/wscons/mra.c rev. 1.6
Fixed wrong cast and invalid array access in the calibration framework,
as documented in PR kern/45872. The AA() macro accessed sample
coordinates as long integers, whereas they are really stored as signed
integers.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.4.64.1 src/sys/dev/wscons/mra.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Masanobu SAITOH <msaitoh@execsw.org>
To: gnats-bugs@NetBSD.org, kern-bug-people@netbsd.org,
gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
Pierre Pronchery <khorben@defora.org>
Cc: msaitoh@execsw.org
Subject: Re: PR/45872 CVS commit: [netbsd-6] src/sys/dev/wscons
Date: Thu, 24 Apr 2014 12:22:07 +0900
Hi, khorben.
(2014/04/11 17:40), SAITOH Masanobu wrote:
> The following reply was made to PR kern/45872; it has been noted by GNATS.
>
> From: "SAITOH Masanobu" <msaitoh@netbsd.org>
> To: gnats-bugs@gnats.NetBSD.org
> Cc:
> Subject: PR/45872 CVS commit: [netbsd-6] src/sys/dev/wscons
> Date: Fri, 11 Apr 2014 08:38:07 +0000
>
> Module Name: src
> Committed By: msaitoh
> Date: Fri Apr 11 08:38:07 UTC 2014
>
> Modified Files:
> src/sys/dev/wscons [netbsd-6]: mra.c
>
> Log Message:
> Pull up following revision(s) (requested by khorben in ticket #1037):
> sys/dev/wscons/mra.c 1.6
>
> Fixed wrong cast and invalid array access in the calibration framework,
> as documented in PR kern/45872. The AA() macro accessed sample
> coordinates as long integers, whereas they are really stored as signed
> integers.
>
>
> To generate a diff of this commit:
> cvs rdiff -u -r1.4 -r1.4.94.1 src/sys/dev/wscons/mra.c
>
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
Are you OK to close this PR?
--
-----------------------------------------------
SAITOH Masanobu (msaitoh@execsw.org
msaitoh@netbsd.org)
State-Changed-From-To: feedback->closed
State-Changed-By: khorben@NetBSD.org
State-Changed-When: Thu, 24 Apr 2014 11:46:30 +0000
State-Changed-Why:
Pull-ups applied, thanks msaitoh@
>Unformatted:
On -current from January 25th, 00:09 CET
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.