Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Jul 2000 09:59:12 +0200
From:      Graham Wheeler <gram@cequrux.com>
To:        stable@freebsd.org
Subject:   Re: psmintr: out of sync (0080 != 0000). ARGH!
Message-ID:  <397D48D0.85169D2@cequrux.com>
References:  <25919.964459652@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------63AE80A793C8D7F1A3ED429D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Just for interest, I've attached the first 120 lines of my hacked
psmintr routine from src/sys/isa/psm.c. I didn't want to send the whole
driver (too large), or a patch (too hard to read without applying), but
this code fragment should convey the gist of what I did to get my
touchpad to work.

There is a synaptics_hack_mode variable. Under normal (sane) behaviour,
this will be set to zero. When the sync gets lost, this is due (in my
experience) to the zero bytes being inserted after the sync byte; in
this case, I set the synaptics_hack_mode variable to one, read four
bytes each time instead of three, and drop the second byte (the zero
byte) from the packet before processing it. If I read a zero byte when
I'm expecting a sync byte, I switch back to the original mode. I can't
remember my justification for doing the latter, but all of this was
based on emperical data gleaned by logging every single byte read by the
driver, and it works for me.

-- 
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
--------------63AE80A793C8D7F1A3ED429D
Content-Type: text/plain; charset=us-ascii;
 name="junk"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="junk"

static void
psmintr(void *arg)
{
    /*
     * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
     * into `mousestatus' button bits (MOUSE_BUTTON?DOWN).
     */
    static int butmap[8] = {
        0, 
	MOUSE_BUTTON1DOWN, 
	MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON2DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, 
	MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
        MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
    };
    static int butmap_versapad[8] = {
	0, 
	MOUSE_BUTTON3DOWN, 
	0, 
	MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN, 
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, 
	MOUSE_BUTTON1DOWN,
	MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN
    };
    static int syncerrs = 0;
    static int synaptics_sync_hack_mode = 0;
    register struct psm_softc *sc = arg;
    mousestatus_t ms;
    int x, y, z;
    int c;
    int l;
    int x0, y0;

    /* read until there is nothing to read */
    while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
    
        /* discard the byte if the device is not open */
        if ((sc->state & PSM_OPEN) == 0)
            continue;
    
        if (syncerrs>0)
	{
	    log(LOG_DEBUG, "psmintr: read %04x (mode %d).\n", c, synaptics_sync_hack_mode);
	    if (--syncerrs == 0)
		log(LOG_DEBUG, "psmintr: stopping logging reads\n");;
	}
	if (sc->hw.model == MOUSE_MODEL_SYNAPTICS &&
	    c==0 && sc->inputbytes == 0)
	{
	    if (synaptics_sync_hack_mode)
	    {
		synaptics_sync_hack_mode = 0;
                log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 1->0\n");
		syncerrs = 10; /* log the next ten reads */
	    }
	    continue;
	}

        /* 
	 * Check sync bits. We check for overflow bits and the bit 3
	 * for most mice. True, the code doesn't work if overflow 
	 * condition occurs. But we expect it rarely happens...
	 */

        
	if (sc->inputbytes == 0) 
        {
	    if (sc->hw.model == MOUSE_MODEL_SYNAPTICS)
	    {
		if ((c&0xCC)!=0x08)
		{
	    	    if (synaptics_sync_hack_mode ==0)
		    {
			synaptics_sync_hack_mode = 1;
                	log(LOG_DEBUG, "psmintr: synaptics_sync_hack_mode 0->1\n");
	                syncerrs = 10; /* log next ten reads */
		    }
                    log(LOG_DEBUG, "psmintr: %04x out of sync.\n", c);
                    continue;
		}
	    }
	    else if (((c & sc->mode.syncmask[0]) != sc->mode.syncmask[1])) {
                log(LOG_DEBUG, "psmintr: out of sync (%04x != %04x).\n", 
		c & sc->mode.syncmask[0], sc->mode.syncmask[1]);
                continue;
	    }
	}

        sc->ipacket[sc->inputbytes++] = c;

	/* If synaptics_sync_hack_mode is one, we read an extra byte */

        if (sc->inputbytes < (sc->mode.packetsize+synaptics_sync_hack_mode)) 
	    continue;

	if (synaptics_sync_hack_mode == 1)
	{
	    if (sc->ipacket[1]==0)
	    {
		/* Drop the byte after the status byte from the packet */
	        sc->ipacket[1] = sc->ipacket[2];
	        sc->ipacket[2] = sc->ipacket[3];
	    }
	}

#if 0
        log(LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
	    sc->ipacket[0], sc->ipacket[1], sc->ipacket[2],
	    sc->ipacket[3], sc->ipacket[4], sc->ipacket[5]);
#endif

	c = sc->ipacket[0];

	/* 
	 * A kludge for Kensington device! 
	 * The MSB of the horizontal count appears to be stored in 
	 * a strange place.

--------------63AE80A793C8D7F1A3ED429D--



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?397D48D0.85169D2>