feat(usb): every xHCI controller is driven, not only the first
boards/BRINGUP.md A1, FABRIC-3 SXLII. xhci.c keeps a table of controllers (up to 8) and services each; kernel_main brings up index 0, 1, ... until there is none. repl.c's and blkio_usb.c's per-slot state is per controller now (a slot ID is a controller's own), and each USB keyboard keeps its own last report and lights; an unplugged keyboard releases what it held. Test first: keyboard and identity on a second controller behind a bridge, Zuse on the first -- before, only Zuse; after, all three, on all three ISAs. Hot-plug and unplug on the second controller. Acceptance unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
739cb9c163
commit
e729c64ba3
+10
-21
@@ -62,11 +62,8 @@ static const uint8_t modifier_key[8] = { 29, 42, 56, 125, 97, 54, 100, 126 };
|
||||
#define KBD_EVENTS 64u
|
||||
static struct { uint16_t keycode; uint8_t pressed; } g_events[KBD_EVENTS];
|
||||
static uint32_t g_head, g_count;
|
||||
static uint8_t g_prev[8];
|
||||
/* Num Lock on to start, matching the console (repl.c); 0xFF = nothing
|
||||
* sent yet, so a new keyboard is always told. */
|
||||
/* Num Lock on to start, matching the console (repl.c). */
|
||||
static uint8_t g_leds_want = USB_KBD_LED_NUM;
|
||||
static uint8_t g_leds_sent = 0xFFu;
|
||||
|
||||
static void push(uint16_t keycode, int pressed)
|
||||
{
|
||||
@@ -89,7 +86,7 @@ static int held(const uint8_t *keys, uint32_t n, uint8_t usage)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usb_kbd_report(const uint8_t *report, uint32_t len)
|
||||
void usb_kbd_report(uint8_t prev[8], const uint8_t *report, uint32_t len)
|
||||
{
|
||||
uint8_t now[8] = {0};
|
||||
uint32_t i, n;
|
||||
@@ -101,34 +98,26 @@ void usb_kbd_report(const uint8_t *report, uint32_t len)
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint8_t bit = (uint8_t)(1u << i);
|
||||
if ((now[0] & bit) != (g_prev[0] & bit)) push(modifier_key[i], (now[0] & bit) != 0);
|
||||
if ((now[0] & bit) != (prev[0] & bit)) push(modifier_key[i], (now[0] & bit) != 0);
|
||||
}
|
||||
n = 6;
|
||||
for (i = 2; i < 8; i++) /* released first, then pressed */
|
||||
if (g_prev[i] > 0x01 && !held(now + 2, n, g_prev[i])) push(key_for(g_prev[i]), 0);
|
||||
if (prev[i] > 0x01 && !held(now + 2, n, prev[i])) push(key_for(prev[i]), 0);
|
||||
for (i = 2; i < 8; i++)
|
||||
if (now[i] > 0x01 && !held(g_prev + 2, n, now[i])) push(key_for(now[i]), 1);
|
||||
if (now[i] > 0x01 && !held(prev + 2, n, now[i])) push(key_for(now[i]), 1);
|
||||
|
||||
for (i = 0; i < 8; i++) g_prev[i] = now[i];
|
||||
for (i = 0; i < 8; i++) prev[i] = now[i];
|
||||
}
|
||||
|
||||
void usb_kbd_reset(void)
|
||||
void usb_kbd_forget(uint8_t prev[8])
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < 8; i++) g_prev[i] = 0;
|
||||
g_leds_sent = 0xFFu;
|
||||
static const uint8_t none[8] = {0};
|
||||
usb_kbd_report(prev, none, 8); /* everything held, released */
|
||||
}
|
||||
|
||||
void usb_kbd_set_leds(uint8_t leds) { g_leds_want = leds; }
|
||||
|
||||
int usb_kbd_leds_pending(uint8_t *leds)
|
||||
{
|
||||
if (g_leds_want == g_leds_sent) return 0;
|
||||
*leds = g_leds_want;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void usb_kbd_leds_sent(uint8_t leds) { g_leds_sent = leds; }
|
||||
uint8_t usb_kbd_leds_wanted(void) { return g_leds_want; }
|
||||
|
||||
int usb_kbd_pop_event(uint16_t *keycode, int *pressed)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user