Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 03 Jul 2000 10:23:05 +0200
From:      Graham Wheeler <gram@cequrux.com>
To:        Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>, freebsd-stable@freebsd.org, support@synaptics.com
Subject:   FreeBSD-4.0S/psmintr out of sync/Synaptics Touchpad
Message-ID:  <a674996d7ac981522746a905617618fd@cequrux.com>
References:  <200006090141.KAA27612@zodiac.mech.utsunomiya-u.ac.jp>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Kazu (and others)

I managed to spend some more time on the problems I have with my
touchpad this weekend, and can report some progress. I'll summarise the
problem, some technical background, and what I have found out so far.

The background: after using the touchpad under FreeBSD-4.0 Stable (with
either X or with moused) for a short period of time, it would go
berserk, and the mouse cursor would jump all over the screen, plus it
would seem like random mouse clicks were being issued. There would also
be lots of "out of sync" log messages. Synchronisation would sometimes
be recovered, but not very easily.

Technical background: The touchpad is manufactured by Synaptics, and
very good documentation is available from their website. According to
them, the touchpad by default should be in "relative mode", in which it
is claimed to be 100% PS/2 mouse compatible. It also has an "absolute
mode", which is what the MS-Windows driver uses. Absolute mode uses
6-byte packets, while relative mode uses 3-byte packets. Absolute mode
is of no further relevance here so I won't discuss it further.

The 3-byte PS/2 packet format consists of a status byte, followed by an
X-delta byte and  Y-delta byte. The status byte has the format:

  X-overflow Y-overflow X-sign Y-sign Reserved Button3 Button2 Button1

The X and Y sign bits are used together with the two 8-bit deltas to
represent the relative motion of the mouse as 9-bit 2's complement
numbers. The X and Y overflow bits get set when the displacement
overflows the 9-bit range. This very rarely happens, and so for all
practical purposes, these bits can be assumed to be zero. The 3 bits
representing button presses are set when the respective button is being
held down; in the case of the touchpad there are only two buttons and so
the Button3 bit is always zero. The Reserved bit is set to 1 for the
Synaptics touchpad; in practice this can be used for "legacy
multiplexing" of multiple PS/2 devices. Such multiplexing is handled by
the keyboard controller. Because of this, the value of the Reserved bit
should usually be treated as "unknown".

The PS/2 protocol does not frame these 3-byte packets, which is why
synchronisation is the biggest single problem in implementing PS/2
drivers. Synchronisation is usually done by examing the first byte read,
and trying to ensure that it is in fact a status byte - typically by
checking that the overflow bits are not set. This is not a very reliable
check, however - it can *eliminate* some non-status bytes as being
considered as candidate status bytes, but certainly not all.



Early experiments: An earlier experiment of mine involved changing the
sync check for the touchpad. I found that on my Compaq Presario 1600
laptop, I could reliably check the Reserved byte (it is always 1); also,
I can use the Button3 bit (it is always zero). So I used a
synchronisation mask of 0xCC, to test the overflow, reserved and button3
bits. The default in the psm driver is just to check the overflow bits.

This helped somewhat, but did not solve the problem. In the course of
doing this, I noticed that when the driver discarded a byte because it
did not appear to be a status byte, the value was typically zero. I then
modified the code to discard zero bytes silently, rather than logging
"out-of-sync". Of course, this didn't affect the reliability, it just
reduced the noise in the logs.


Recent experiments: I removed the code to silently drop zero bytes. I
changed the sync check from the usual one in the psm driver, which is:

  if ((last_sync_value & sync_mask) != (new_sync_value & sync_mask))
  {
    drop new_sync_value;
    log sync problem;
    continue;
  }

to the following:

  if ((new_sync_value & 0xCC) != 0x80)...

This may not have made any real difference, but it did allow me to know
that I would not try to test against a *bad* last_sync_value.

I also changed the code so that after a few hundred sync problems, the
driver would start logging all the bytes it read from the mouse.

Things were terrible, and I almost immediately started getting all the
bytes logged. I then experimented by moving my finger to the right (i.e.
significant positive X delta, minimal Y-delta), to the left (significant
negative X, minimal Y), up, and down. This allowed me to see something
very interesting: after the status byte came the zero byte, followed by
the X byte and then the Y byte. So the packet size, as seen by the psm
driver, is actually 4-bytes, not 3.

I don't know whether this is due to some weird bug in the touchpad, or
due to some weird bug in the keyboard controller code.

I then kludged the driver code to read 4-byte packets, to check that the
first byte matched my sync check above, and that the second byte was
zero, and if so, I copy the third byte value to the second byte, and the
fourth byte to the third. It's ugly, but this has almost entirely
eliminated the out-of-sync messages. Furthermore, when the mouse does
lose sync, it now recovers almost immediately.

So I think I have solved my problem in practice, but I don't know why
the driver is seeing this extra zero byte, and why I am having to do
this ugly kludge. In fact, I am thinking of kludging things more, to try
to eliminate the remaining sync problems, by restricting the acceptable
packets to those with fairly small deltas. Something like:

Accept iff ((X-sign==0 && X-delta<0x20) || (X-sign==1 && X-delta>0xD0))

and similarly for Y (treating the deltas as unsigned values in these
tests).

regards
Graham
-- 
Dr Graham Wheeler                        E-mail: gram@cequrux.com
Director, Research and Development       WWW:    http://www.cequrux.com
CEQURUX Technologies                     Phone:  +27(21)423-6065
Firewalls/VPN Specialists                Fax:    +27(21)424-3656


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?a674996d7ac981522746a905617618fd>