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:
rajames
2026-10-14 14:27:38 -04:00
co-authored by Claude Opus 5.5
parent 739cb9c163
commit e729c64ba3
27 changed files with 81701 additions and 260 deletions
+11 -9
View File
@@ -20,25 +20,27 @@
#include <stdint.h>
/* One boot report: byte 0 the modifier bits, byte 1 reserved, bytes 2-7
* up to six keys held (HID usage IDs). `len` below 3 is ignored. */
void usb_kbd_report(const uint8_t *report, uint32_t len);
* up to six keys held (HID usage IDs). `len` below 3 is ignored. `prev`
* is that keyboard's own last report, 8 bytes, kept by the caller -- each
* keyboard is compared with itself, never with another. */
void usb_kbd_report(uint8_t prev[8], const uint8_t *report, uint32_t len);
/* Forgets the keys held: the keyboard has gone. */
void usb_kbd_reset(void);
/* The keyboard has gone: every key it still held is released, and its
* last report forgotten -- no Shift stays down after it. */
void usb_kbd_forget(uint8_t prev[8]);
/* The next key event: 1 with *keycode (Linux) and *pressed (1/0), or 0. */
int usb_kbd_pop_event(uint16_t *keycode, int *pressed);
/* The lock lights (boot output report bits, HID 1.11 appendix B.1). The
* console says which locks are on; the xHCI driver sends them to the
* console says which locks are on; the xHCI driver sends them to each
* keyboard with SET_REPORT whenever they differ from what it last sent. */
#define USB_KBD_LED_NUM 0x01u
#define USB_KBD_LED_CAPS 0x02u
#define USB_KBD_LED_SCROLL 0x04u
void usb_kbd_set_leds(uint8_t leds);
/* 1 and the lights to send if they changed since last sent, else 0. */
int usb_kbd_leds_pending(uint8_t *leds);
/* The driver has sent these. */
void usb_kbd_leds_sent(uint8_t leds);
/* The lights every keyboard should show. Each keyboard's driver state
* holds what that keyboard was last sent. */
uint8_t usb_kbd_leds_wanted(void);
#endif /* STARKERNEL_USB_KBD_H */