The PS/2 scan-code translation you implement here — make codes, break codes, the shift/caps-lock XOR trick — is exactly what every BIOS and early Linux console driver did before USB HID keyboards became standard. Confusing a break code for a make code is a classic bug that makes a kernel think a key is still held down forever after it's released.