From owner-freebsd-stable Mon Jul 3 1:24:18 2000 Delivered-To: freebsd-stable@freebsd.org Received: from citadel.cequrux.com (citadel.cequrux.com [192.96.22.18]) by hub.freebsd.org (Postfix) with ESMTP id DD34537B52E for ; Mon, 3 Jul 2000 01:24:00 -0700 (PDT) (envelope-from gram@cequrux.com) Received: (from nobody@localhost) by citadel.cequrux.com (8.8.8/8.6.9) id KAA02495; Mon, 3 Jul 2000 10:22:44 +0200 (SAST) Received: by citadel.cequrux.com via recvmail id 2380; Mon Jul 3 10:21:43 2000 Message-ID: Date: Mon, 03 Jul 2000 10:23:05 +0200 From: Graham Wheeler Organization: Cequrux Technologies X-Mailer: Mozilla 4.7 [en] (X11; U; FreeBSD 2.2.8-RELEASE i386) X-Accept-Language: en MIME-Version: 1.0 To: Kazutaka YOKOTA , freebsd-stable@freebsd.org, support@synaptics.com Subject: FreeBSD-4.0S/psmintr out of sync/Synaptics Touchpad References: <200006090141.KAA27612@zodiac.mech.utsunomiya-u.ac.jp> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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