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
@@ -30,20 +30,33 @@ typedef struct {
|
||||
* controller's own max_slots, allocated once on first use here since this
|
||||
* file has no bringup-time hook of its own to do it earlier). Indexed
|
||||
* directly by xHCI slot ID, index 0 unused, matching msc_slots[]. */
|
||||
static BlkioUsbState *g_usb_blk_slots = NULL;
|
||||
static uint32_t g_usb_blk_slot_count = 0;
|
||||
|
||||
/* One registry per controller (2026-10-14: every xHCI controller is now
|
||||
* driven, and a slot ID is a controller's own -- slot 1 on two
|
||||
* controllers is two devices). Found by the controller's own pointer. */
|
||||
static struct {
|
||||
xhci_dev_t *xdev;
|
||||
BlkioUsbState *slots;
|
||||
uint32_t count;
|
||||
} g_usb_blk[XHCI_MAX_CONTROLLERS];
|
||||
|
||||
static BlkioUsbState *usb_blk_state_for(xhci_dev_t *xdev, uint32_t slot_id) {
|
||||
uint32_t c;
|
||||
if (!xdev || slot_id < 1 || slot_id > xdev->max_slots) return NULL;
|
||||
if (!g_usb_blk_slots || g_usb_blk_slot_count < xdev->max_slots + 1) {
|
||||
for (c = 0; c < XHCI_MAX_CONTROLLERS; c++) {
|
||||
if (g_usb_blk[c].xdev == xdev || !g_usb_blk[c].xdev) break;
|
||||
}
|
||||
if (c == XHCI_MAX_CONTROLLERS) return NULL;
|
||||
if (!g_usb_blk[c].slots || g_usb_blk[c].count < xdev->max_slots + 1) {
|
||||
size_t bytes = (size_t)(xdev->max_slots + 1) * sizeof(BlkioUsbState);
|
||||
BlkioUsbState *fresh = (BlkioUsbState *)kmalloc_aligned(bytes, 64);
|
||||
if (!fresh) return NULL;
|
||||
memset(fresh, 0, bytes);
|
||||
g_usb_blk_slots = fresh;
|
||||
g_usb_blk_slot_count = xdev->max_slots + 1;
|
||||
g_usb_blk[c].xdev = xdev;
|
||||
g_usb_blk[c].slots = fresh;
|
||||
g_usb_blk[c].count = xdev->max_slots + 1;
|
||||
}
|
||||
return &g_usb_blk_slots[slot_id];
|
||||
return &g_usb_blk[c].slots[slot_id];
|
||||
}
|
||||
|
||||
static int usb_blk_open(blkio_dev_t *dev, const blkio_params_t *p) {
|
||||
|
||||
Reference in New Issue
Block a user