Subject: wskbd problem with X11 (was: XFree86 4.2 on late 2001 iBook)
To: None <port-macppc@netbsd.org>
From: Aymeric Vincent <xmimx@free.fr>
List: tech-x11
Date: 04/05/2002 14:59:53
        Hi,

the first bug I was speaking about disappeared after I actually
compiled a newer X server with Charles' patches applied. The X build
did not fail when the X server failed to build and install, and I was
innoncently running a pre-compiled version of the server. Thanks
Thomas for pointing me at the impossibility of what I said. ;-)

However, the second bug remains, and it is wscons-related.

Aymeric Vincent <xmimx@free.fr> writes:

> - Another bug in the X server is that when I logout from my login
>   xterm, the X server often tries to quit but seems to be stuck in an
>   infinite loop, taking almost all the CPU, and apparently doing a lot
>   of syscalls because most of the CPU percentage is taken by the
>   system. Remotely killing the X server works here and xdm starts
>   another server.

When it (re-)inits itself, the X server flushes its keyboard
input. However, this is handled by xf86FlushInput
(in hw/os-support/bsd/posix_support.c) which apparently expects its
argument to be a terminal (tcflush() call).

int
xf86FlushInput(int fd)
{
        fd_set fds;
        struct timeval timeout;
        char c[4];

        if (tcflush(fd, TCIFLUSH) == 0)
                return 0;

        timeout.tv_sec = 0;
        timeout.tv_usec = 0;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
                read(fd, &c, sizeof(c));
                FD_ZERO(&fds);
                FD_SET(fd, &fds);
        }
        return 0;
}

The call to tcflush() fails and the X server then repeatedly reads
keys from /dev/wskbd0, hoping to flush it...

This is what I suspect because of this k-trace:

 23314 XFree86  CALL  ioctl(0x4,TIOCFLUSH,0x7fffea78)
 23314 XFree86  RET   ioctl -1 errno 25 Inappropriate ioctl for device
 23314 XFree86  CALL  select(0x100,0x7fffea98,0,0,0x7fffeab8)
 23314 XFree86  RET   select 1
 23314 XFree86  CALL  read(0x4,0x7fffeac0,0x4)
 23314 XFree86  RET   read -1 errno 40 Message too long
 23314 XFree86  CALL  select(0x100,0x7fffea98,0,0,0x7fffeab8)
 23314 XFree86  RET   select 1
 23314 XFree86  CALL  read(0x4,0x7fffeac0,0x4)
 23314 XFree86  RET   read -1 errno 40 Message too long
 ... goes on forever ...

(fd 4 is /dev/wskbd0 as reported by fstat)

It looks like the X server handles wskbd's wrongly but however, this
code is MI and works fine on other architectures (this is under
macppc) so the right fix might be to implement a flush ioctl in the
keyboard driver... Any thoughts?

Maybe this is related to the fact that we have to use /dev/wskbd0
instead of /dev/wskbd on macppc?

From an X server point of view, I guess we have to:

 - quit the loop if read() fails
 - put a (huge) limit to the number of iterations, "just in case"
 - read() by chunks the size of a wscons event instead of 4 bytes
   because that's where the problem comes from in the first place.

 Aymeric