[Top][All Lists]
[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);