qemu-devel
[Top][All Lists]
Advanced

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

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


From: Marcelo Tosatti
Subject: Re: [Qemu-devel] [SOLUTION] "i8042.c: No controller found" -> OS sees no keyboard if I type "in BIOS"
Date: Mon, 8 Jun 2009 11:30:21 -0300
User-agent: Mutt/1.5.19 (2009-01-05)

On Mon, Jun 08, 2009 at 04:13:09PM +0200, Tomasz Chmielewski wrote:
> Tomasz Chmielewski wrote:
>> Marcelo Tosatti wrote:
>>
>>>> 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.
>>>
>>> However i'm not familiar with PS/2 or i8042. Anthony?
>>
>> This:
>>
>> #define KBD_QUEUE_SIZE 256
>>
>> dates back to qemu-0.5.1, where it was defined in vl.c.
>>
>> Seems like it's in Qemu from the very beginning?
>>
>>
>> PS2_QUEUE_SIZE 256 was introduced in qemu-0.8.0.
>
> BTW, with "PS2_QUEUE_SIZE 16" I'm still able to trigger:
>
> i8042.c: No controller found.

I was not able to trigger it by changing PS2_QUEUE_SIZE to 16 (which
shows the testing was lame, since you did trigger it).

> Only with "PS2_QUEUE_SIZE 15" keyboard is detected every time I boot the  
> guest (unless that's what you meant by setting it to 16).

No, 16. Maybe there's some off-by-one bug in hw/ps2.c? Also yesterday i
was not entirely sure the KBD_STAT_OBF (output buffer empty/full status
bit) handling was correct (thus the attached patch), but now a quick
look seems to indicate it is alright, since it be will update these bits
via:

ps2_read_data
->update_irq(s->update_arg, q->count != 0)
kbd_update_irq


diff --git a/hw/pckbd.c b/hw/pckbd.c
index 3ef3594..7d21994 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -181,6 +181,13 @@ static uint32_t kbd_read_status(void *opaque, uint32_t 
addr)
 {
     KBDState *s = opaque;
     int val;
+
+    if (ps2_buffer_empty(s->kbd))
+       s->status &= ~KBD_STAT_OBF;
+
+    if (ps2_buffer_empty(s->mouse))
+       s->status &= ~KBD_STAT_MOUSE_OBF;
+
     val = s->status;
 #if defined(DEBUG_KBD)
     printf("kbd: read status=0x%02x\n", val);
diff --git a/hw/ps2.c b/hw/ps2.c
index b1352d0..0f9bd67 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 16
 
 typedef struct {
     uint8_t data[PS2_QUEUE_SIZE];
@@ -181,6 +181,15 @@ uint32_t ps2_read_data(void *opaque)
     return val;
 }
 
+int ps2_buffer_empty(void *opaque)
+{
+    PS2State *s = (PS2State *)opaque;
+    PS2Queue *q;
+
+    q = &s->queue;
+    return (q->count == 0);
+}
+
 static void ps2_reset_keyboard(PS2KbdState *s)
 {
     s->scan_enabled = 1;
diff --git a/hw/ps2.h b/hw/ps2.h
index 32a4231..af76c92 100644
--- a/hw/ps2.h
+++ b/hw/ps2.h
@@ -4,6 +4,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void 
*update_arg);
 void ps2_write_mouse(void *, int val);
 void ps2_write_keyboard(void *, int val);
 uint32_t ps2_read_data(void *);
+int ps2_buffer_empty(void *);
 void ps2_queue(void *, int b);
 void ps2_keyboard_set_translation(void *opaque, int mode);
 void ps2_mouse_fake_event(void *opaque);




reply via email to

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