Wait for ACKs when setting the mode
This commit is contained in:
parent
b88904ca7f
commit
7ae3eb6232
2 changed files with 31 additions and 9 deletions
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#define KEYBOARD_AT_TRANSLATE 0x40
|
#define KEYBOARD_AT_TRANSLATE 0x40
|
||||||
|
|
||||||
|
#define GRUB_AT_ACK 0xfa
|
||||||
|
|
||||||
#define KEYBOARD_ISMAKE(x) !((x) & 0x80)
|
#define KEYBOARD_ISMAKE(x) !((x) & 0x80)
|
||||||
#define KEYBOARD_ISREADY(x) ((x) & 0x01)
|
#define KEYBOARD_ISREADY(x) ((x) & 0x01)
|
||||||
#define KEYBOARD_SCANCODE(x) ((x) & 0x7f)
|
#define KEYBOARD_SCANCODE(x) ((x) & 0x7f)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/keyboard_layouts.h>
|
#include <grub/keyboard_layouts.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
|
||||||
static short at_keyboard_status = 0;
|
static short at_keyboard_status = 0;
|
||||||
static int e0_received = 0;
|
static int e0_received = 0;
|
||||||
|
@ -225,19 +226,29 @@ grub_keyboard_controller_write (grub_uint8_t c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_mode (int mode)
|
wait_ack (void)
|
||||||
{
|
{
|
||||||
grub_uint8_t ack;
|
grub_uint8_t ack;
|
||||||
|
grub_uint64_t endtime = grub_get_time_ms () + 20;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ack = grub_inb (KEYBOARD_REG_DATA);
|
||||||
|
}
|
||||||
|
while (ack != GRUB_AT_ACK && grub_get_time_ms () < endtime);
|
||||||
|
grub_dprintf ("atkeyb", "Ack 0x%02x\n", ack);
|
||||||
|
return ack == GRUB_AT_ACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_mode (int mode)
|
||||||
|
{
|
||||||
keyboard_controller_wait_until_ready ();
|
keyboard_controller_wait_until_ready ();
|
||||||
grub_outb (0xf0, KEYBOARD_REG_DATA);
|
grub_outb (0xf0, KEYBOARD_REG_DATA);
|
||||||
keyboard_controller_wait_until_ready ();
|
keyboard_controller_wait_until_ready ();
|
||||||
grub_outb (mode, KEYBOARD_REG_DATA);
|
grub_outb (mode, KEYBOARD_REG_DATA);
|
||||||
keyboard_controller_wait_until_ready ();
|
keyboard_controller_wait_until_ready ();
|
||||||
ack = grub_inb (KEYBOARD_REG_DATA);
|
|
||||||
if (ack != 0xfa)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
return wait_ack ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -254,7 +265,7 @@ query_mode (void)
|
||||||
|
|
||||||
do
|
do
|
||||||
ret = grub_inb (KEYBOARD_REG_DATA);
|
ret = grub_inb (KEYBOARD_REG_DATA);
|
||||||
while (ret == 0xfa);
|
while (ret == GRUB_AT_ACK);
|
||||||
|
|
||||||
/* QEMU translates the set even in no-translate mode. */
|
/* QEMU translates the set even in no-translate mode. */
|
||||||
if (ret == 0x43 || ret == 1)
|
if (ret == 0x43 || ret == 1)
|
||||||
|
@ -275,6 +286,7 @@ set_scancodes (void)
|
||||||
knowledge. Assume XT. */
|
knowledge. Assume XT. */
|
||||||
if (!grub_keyboard_orig_set)
|
if (!grub_keyboard_orig_set)
|
||||||
{
|
{
|
||||||
|
grub_dprintf ("atkeyb", "No sets support assumed\n");
|
||||||
current_set = 1;
|
current_set = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -284,11 +296,13 @@ set_scancodes (void)
|
||||||
|
|
||||||
write_mode (2);
|
write_mode (2);
|
||||||
current_set = query_mode ();
|
current_set = query_mode ();
|
||||||
|
grub_dprintf ("atkeyb", "returned set %d\n", current_set);
|
||||||
if (current_set == 2)
|
if (current_set == 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
write_mode (1);
|
write_mode (1);
|
||||||
current_set = query_mode ();
|
current_set = query_mode ();
|
||||||
|
grub_dprintf ("atkeyb", "returned set %d\n", current_set);
|
||||||
if (current_set == 1)
|
if (current_set == 1)
|
||||||
return;
|
return;
|
||||||
grub_printf ("No supported scancode set found\n");
|
grub_printf ("No supported scancode set found\n");
|
||||||
|
@ -334,7 +348,7 @@ fetch_key (int *is_break)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setting LEDs may generate ACKs. */
|
/* Setting LEDs may generate ACKs. */
|
||||||
if (at_key == 0xfa)
|
if (at_key == GRUB_AT_ACK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
was_ext = e0_received;
|
was_ext = e0_received;
|
||||||
|
@ -540,8 +554,14 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus
|
||||||
pending_key = -1;
|
pending_key = -1;
|
||||||
at_keyboard_status = 0;
|
at_keyboard_status = 0;
|
||||||
/* Drain input buffer. */
|
/* Drain input buffer. */
|
||||||
while (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
|
while (1)
|
||||||
|
{
|
||||||
|
keyboard_controller_wait_until_ready ();
|
||||||
|
if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
|
||||||
|
break;
|
||||||
|
keyboard_controller_wait_until_ready ();
|
||||||
grub_inb (KEYBOARD_REG_DATA);
|
grub_inb (KEYBOARD_REG_DATA);
|
||||||
|
}
|
||||||
grub_keyboard_controller_orig = grub_keyboard_controller_read ();
|
grub_keyboard_controller_orig = grub_keyboard_controller_read ();
|
||||||
set_scancodes ();
|
set_scancodes ();
|
||||||
keyboard_controller_led (led_status);
|
keyboard_controller_led (led_status);
|
||||||
|
|
Loading…
Reference in a new issue