All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dinesh Subhraveti" <subhraveti@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [SOLUTION] "i8042.c: No controller found" ->OS	sees no keyboard if I type "in BIOS"
Date: Thu, 9 Jul 2009 13:52:09 -0700	[thread overview]
Message-ID: <h35lah$le7$1@ger.gmane.org> (raw)
In-Reply-To: loom.20090709T005828-509@post.gmane.org


"Dinesh Subhraveti" <dineshs@us.ibm.com> wrote in message 
news:loom.20090709T005828-509@post.gmane.org...
> Marcelo Tosatti <mtosatti <at> redhat.com> writes:
>
>>
>> On Wed, May 20, 2009 at 03:30:09PM +0200, Tomasz Chmielewski wrote:
>> > 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)?
>>
>> All references (*) i could find mention 16 bytes of output buffer
>> (including the Linux source as you mentioned, which was reduced from 32
>> to 16 somewhere in the 2.6.10 era).
>>
>> http://www.computer-engineering.org/ps2protocol/
>>
>> http://linux.bkbits.net:8080/linux-2.6.28-stable/drivers/input/serio/i8042.h?
> PAGE=diffs&REV=4203735dp_doSExYU6ido8KnczbjzQ
>>
>> Reducing PS2_QUEUE_SIZE to 16 also makes the Linux detection loop happy.
>>
>> If QEMU claims to emulate i8042, it should be similar to real hardware.
>
> Some new findings on this old thread:
>
> Reducing PS2_QUEUE_SIZE to 16 prevents the PS2 mouse event handler
> (ps2_mouse_event()) from queuing any mouse events.  It checks if there is 
> at
> least 16 bytes of space left in the queue, if not, the event is dropped.
>
> The side effect of this is that, the buffer will not become full, and
> i8042_controller_check() in the guest passes the check and keyboard works
> normally after reboot.  However, mouse remains inactive throughout, 
> because
> its events are always dropped.
>
> Two questions:
>
> - Does it make sense to reduce the size of reserved space (currently 16 
> bytes)
> checked by ps2_mouse_event()?  It will probably break other things since 
> the
> size of reserved space is tied to the distance mouse is moved.  If the
> distance moved can fit in 1 byte (+/- 128), it is queued as one event. 
> For
> longer distances, it is queued as multiple events, requiring more buffer
> space.  16 bytes is probably a conservative estimate of the longest 
> distance
> moved.
>
> - Why does the guest kernel (i8042_controller_check()) conclude that there 
> is
> no i8042 controller if it finds the queue to be full?  Reducing 
> PS2_QUEUE_SIZE
> to 16 is still not enough.  It need to be something less than 16 for the 
> guest
> kernel to successfully detect the controller.
>
> Interestingly, the problem is not seen on RHEL 5.3.  It leaves the mouse
> disabled on shutdown via AUX_DISABLE_DEV mouse command.  AUX_DISABLE_DEV
> command resets MOUSE_STATUS_ENABLED flag in PS2MouseState->mouse_status, 
> which
> makes mouse events to be dropped by ps2_mouse_event().
>
> On SLES 11, however, mouse is disabled but then it is again re-enabled 
> (via
> AUX_ENABLE_DEV) prior to resetting the processor, which leaves the mouse
> enabled during BIOS.  Not clear what makes the guest re-enable the mouse 
> on
> shutdown.
>
> Folks have some clues on the right way to address this?
>

Sorry for the duplicate message above (mail server was taking hours to post, 
and I got impatient...)

Changing PS2_QUEUE_SIZE to 15 and the "reserved space" to 8 fixes the 
problem for me:

diff --git a/hw/ps2.c b/hw/ps2.c
index fb77005..51a3ab8 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -70,7 +70,7 @@
 #define MOUSE_STATUS_ENABLED    0x20
 #define MOUSE_STATUS_SCALE21    0x10

-#define PS2_QUEUE_SIZE 256
+#define PS2_QUEUE_SIZE 15

 typedef struct {
     uint8_t data[PS2_QUEUE_SIZE];
@@ -346,7 +346,7 @@ static void ps2_mouse_event(void *opaque,
     s->mouse_buttons = buttons_state;

     if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
-        (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
+        (s->common.queue.count < (PS2_QUEUE_SIZE - 8))) {
         for(;;) {
             /* if not remote, send event. Multiple events are sent if
                too big deltas */

Both keyboard and mouse remain responsive after reboot, no matter how much I 
type / move the mouse during reboot.

Any comments?

Thanks,
Dinesh Subhraveti 

  reply	other threads:[~2009-07-09 20:52 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-14 13:57 [Qemu-devel] "i8042.c: No controller found" -> OS sees no keyboard if I type "in BIOS" Tomasz Chmielewski
2009-05-20  9:30 ` Tomasz Chmielewski
2009-05-20 13:30   ` [Qemu-devel] [SOLUTION] " Tomasz Chmielewski
2009-06-07  4:04     ` Marcelo Tosatti
2009-06-08 13:51       ` Tomasz Chmielewski
2009-06-08 14:13         ` Tomasz Chmielewski
2009-06-08 14:30           ` Marcelo Tosatti
2009-06-08 15:11             ` Tomasz Chmielewski
2009-06-08 15:48               ` Mark Cave-Ayland
2009-06-23 12:27                 ` Mark Cave-Ayland
2009-06-08 14:59           ` Avi Kivity
2009-06-08 15:08             ` Tomasz Chmielewski
2009-06-08 15:28             ` Paul Brook
2009-07-08 21:08       ` [Qemu-devel] " Dinesh Subhraveti
2009-07-09  1:07       ` Dinesh Subhraveti
2009-07-09 20:52         ` Dinesh Subhraveti [this message]
2009-07-10  8:21           ` [Qemu-devel] Re: [SOLUTION] "i8042.c: No controller found" ->OS " Mark Cave-Ayland
2009-07-10 21:45             ` Dinesh Subhraveti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='h35lah$le7$1@ger.gmane.org' \
    --to=subhraveti@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.