irq: turn a PS/2 line over when its device waits and nothing comes
An ASUS TUF A15 booted with its internal keyboard dead and a USB one fine. These AMD laptops' firmware describes IRQ 1's polarity wrongly -- Linux keeps a quirk list -- and an edge line programmed the wrong way up never fires: the controller holds its byte, and only the interrupt that never comes would read it. irq_watch() lets a driver say how to ask its device whether something is waiting. The poller asks every tick; 50 ms of waiting with nothing delivered turns the line's polarity over and drains the device, which re-arms the edge, and if it still says nothing the line is polled. Both are announced. The keyboard and the PS/2 mouse are watched. ISA lines now also take their mode from the MADT's override entries, which were parsed and never read. Tested in QEMU, which ignores polarity on edge lines, with the keyboard line masked: the first key turns it over and typing works; masked again after the flip, it is polled and typing still works. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
726091000e
commit
8c426b2077
4 changed files with 123 additions and 0 deletions
|
|
@ -48,6 +48,15 @@ mouse_read(void)
|
|||
return inb(KBD_S_DATA);
|
||||
}
|
||||
|
||||
// A byte from the auxiliary port, which IRQ 12 should have announced; see
|
||||
// kbd_waiting() in console.c.
|
||||
static int
|
||||
mouse_waiting(void)
|
||||
{
|
||||
uchar st = inb(KBD_S_STAT);
|
||||
return st != 0xFF && (st & 0x21) == 0x21;
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_irq(void *arg)
|
||||
{
|
||||
|
|
@ -262,4 +271,5 @@ mouseinit(void)
|
|||
mouse_read();
|
||||
|
||||
irq_register(IRQ_MOUSE, mouse_irq, 0, "ps2-mouse", 0);
|
||||
irq_watch(IRQ_MOUSE, mouse_waiting);
|
||||
}
|
||||
Loading…
Reference in a new issue