qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [SOLUTION] "i8042.c: No controller found" -> OS sees no key


From: Tomasz Chmielewski
Subject: [Qemu-devel] [SOLUTION] "i8042.c: No controller found" -> OS sees no keyboard if I type "in BIOS"
Date: Wed, 20 May 2009 15:30:09 +0200
User-agent: Thunderbird 2.0.0.21 (X11/20090319)

Tomasz Chmielewski schrieb:

When I boot the guest and type (just hit any keys) in the VNC window before the operating system boots, sometimes, the system loads with no keyboard present - as signified in dmesg on guest:

i8042.c: No controller found

As a result, I can't use the keyboard in the VNC window.

drivers/input/serio/i8042.c in the Linux kerne has this:

static int i8042_controller_check(void)
{
        if (i8042_flush() == I8042_BUFFER_SIZE) {
                printk(KERN_ERR "i8042.c: No controller found.\n");
                return -ENODEV;
        }

        return 0;
}


So, can it be that if we type anything on keyboard (or move mouse) while Qemu's BIOS is still booting or later in the bootloader (GRUB, lilo), some buffer is not flushed and Linux gets confused? And as a result, decides there is no keyboard?

Yes, this is what seems to happen - Qemu's keyboard buffer seems to be infinite
or at least very big; normal 8042 devices have buffer of 16 bytes only.

If we add "i8042.debug" parameter to kernel command line,
we will see how many characters were flushed during boot, i.e.:


drivers/input/serio/i8042.c: ff <- i8042 (flush, aux) [0]
drivers/input/serio/i8042.c: 18 <- i8042 (flush, aux) [0]
drivers/input/serio/i8042.c: 92 <- i8042 (flush, aux) [0]
drivers/input/serio/i8042.c: 00 <- i8042 (flush, aux) [0]
(...)


With this 16 byte buffer in drivers/input/serio/i8042.h (before 2.6.11 it was
32 bytes I think):

#define I8042_BUFFER_SIZE       16


and this piece of code in drivers/input/serio/i8042.c:


/*
* i8042_flush() flushes all data that may be in the keyboard and mouse buffers
* of the i8042 down the toilet.
*/

static int i8042_flush(void)
{
       unsigned long flags;
       unsigned char data, str;
       int i = 0;

       spin_lock_irqsave(&i8042_lock, flags);

       while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < 
I8042_BUFFER_SIZE)) {
               udelay(50);
               data = i8042_read_data();
               i++;
               dbg("%02x <- i8042 (flush, %s)", data,
                       str & I8042_STR_AUXDATA ? "aux" : "kbd");
       }

       spin_unlock_irqrestore(&i8042_lock, flags);

       return i;
}



Linux kernel thinks there is no controller:


(...)
drivers/input/serio/i8042.c: 28 <- i8042 (flush, aux) [0]
drivers/input/serio/i8042.c: 00 <- i8042 (flush, aux) [0]
i8042.c: No controller found.


If we increase "I8042_BUFFER_SIZE" to 256 or more, we have a much better chance that a booted Linux will have a keyboard present.

So, who's to be blamed?

Linux kernel for having its i8042 buffer to small (16 bytes), fixable with:


--- i8042.h.orig        2009-05-20 15:26:32.000000000 +0200
+++ i8042.h     2009-05-20 15:26:32.000000000 +0200
@@ -73,7 +73,7 @@
 * the i8042 buffers.
 */

-#define I8042_BUFFER_SIZE      16
+#define I8042_BUFFER_SIZE      256

/*
 * Number of AUX ports on controllers supporting active multiplexing



Or Qemu, for having its keyboard buffer too large (I'm not sure, but probably 
256 bytes)?


--
Tomasz Chmielewski
http://wpkg.org




reply via email to

[Prev in Thread] Current Thread [Next in Thread]