GMMOS: I2C keyboards, and every keyboard at once
The second micro driver: i2c_hid.c with everything but reading a keyboard's input reports taken out. No ACPI -- AML cannot run on a dead kernel -- so the live driver hands over what it found at boot (i2c_hid_keyboards): the DesignWare controller, the address, the report size, the AMD GPIO pin if there is one, and the parsed report descriptor. No power commands, no reset, a read-only transfer. usb_hid.c's report-protocol rewrite is split out as hid_boot_report(), which does nothing but rewrite, and kernel/gmmos/hidkeys.c turns boot reports into keys for this and the USB micro drivers to come. GMMOS now probes every micro driver and polls all that answer. Not run: QEMU has no DesignWare I2C, and the laptops at hand have PS/2 keyboards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
cb9b06d46f
commit
c6d90e69fa
8 changed files with 387 additions and 17 deletions
|
|
@ -525,19 +525,19 @@ bits(const uchar *p, int len, int bit, int size)
|
|||
// A report-protocol keyboard report, rewritten as a boot one: modifiers, a
|
||||
// reserved byte, six usages. Six is a limit only of the rewrite; the seventh
|
||||
// key held at once is dropped, which is what a boot keyboard does too.
|
||||
static void
|
||||
report_keyboard(struct hid *h, const uchar *rep, int len)
|
||||
// Nothing else happens here, which is what lets GMMOS call it after a panic.
|
||||
static int
|
||||
to_boot(struct hid *h, const uchar *rep, int len, uchar *boot)
|
||||
{
|
||||
uchar boot[8];
|
||||
int i, n = 0;
|
||||
|
||||
if(h->kbd_id){
|
||||
if(len < 1 || rep[0] != h->kbd_id)
|
||||
return;
|
||||
return 0;
|
||||
rep++;
|
||||
len--;
|
||||
}
|
||||
memset(boot, 0, sizeof(boot));
|
||||
memset(boot, 0, 8);
|
||||
for(i = 0; i < 8; i++)
|
||||
if(h->mod_bit[i] >= 0 && bits(rep, len, h->mod_bit[i], 1))
|
||||
boot[0] |= 1 << i;
|
||||
|
|
@ -555,7 +555,36 @@ report_keyboard(struct hid *h, const uchar *rep, int len)
|
|||
if(n < 6)
|
||||
boot[2 + n++] = u;
|
||||
}
|
||||
keyboard_report(h, boot, sizeof(boot));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
report_keyboard(struct hid *h, const uchar *rep, int len)
|
||||
{
|
||||
uchar boot[8];
|
||||
|
||||
if(to_boot(h, rep, len, boot))
|
||||
keyboard_report(h, boot, sizeof(boot));
|
||||
}
|
||||
|
||||
int
|
||||
hid_is_keyboard(void *hv)
|
||||
{
|
||||
struct hid *h = hv;
|
||||
return h && (h->rkbd || h->proto == USB_HID_PROTO_KEYBOARD);
|
||||
}
|
||||
|
||||
int
|
||||
hid_boot_report(void *hv, const uchar *rep, int len, uchar *boot)
|
||||
{
|
||||
struct hid *h = hv;
|
||||
|
||||
if(h->rkbd)
|
||||
return to_boot(h, rep, len, boot);
|
||||
if(h->proto != USB_HID_PROTO_KEYBOARD || len < 8)
|
||||
return 0;
|
||||
memmove(boot, rep, 8);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
Loading…
Reference in a new issue