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
@@ -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 */
|
||||
|
||||
@@ -147,6 +147,8 @@ typedef struct {
|
||||
uint32_t hid_ring_cycle;
|
||||
uint32_t hid_ring_enq;
|
||||
uint8_t *hid_buf;
|
||||
uint8_t hid_prev[8]; /* this keyboard's last report (usb_kbd.c) */
|
||||
uint8_t hid_leds_sent; /* lights last sent to it; 0xFF = none yet */
|
||||
|
||||
uint8_t bot_msc_attach_pending;
|
||||
uint8_t bot_msc_attached;
|
||||
@@ -419,17 +421,24 @@ typedef struct {
|
||||
} xhci_dev_t;
|
||||
|
||||
/*
|
||||
* xhci_find_and_map — locate the xHCI controller on PCI bus 0, enable it
|
||||
* (I/O+MEM+bus-master), map its BAR0 MMIO region, and
|
||||
* fill in the four register-region pointers in *dev.
|
||||
* xhci_find_and_map — locate the index-th xHCI controller (0 = the first
|
||||
* found, by PCI class, on any bus), enable it
|
||||
* (I/O+MEM+bus-master), take it from the firmware, map
|
||||
* its BAR0 MMIO region, and fill in the four
|
||||
* register-region pointers in *dev. Every controller
|
||||
* is driven since 2026-10-14 (kernel_main.c brings up
|
||||
* index 0, 1, ... until there is none), each its own
|
||||
* xhci_dev_t.
|
||||
*
|
||||
* dev must point to a zero-initialised xhci_dev_t.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns -1 if no xHCI device was found on the PCI bus.
|
||||
* Returns -2 if the BAR0 mapping failed.
|
||||
* Returns 1 if there is no index-th controller (there are fewer).
|
||||
* Returns -1 if this one's BAR0 cannot be read, -2 if it cannot be mapped
|
||||
* (the next controller may still be fine).
|
||||
*/
|
||||
int xhci_find_and_map(xhci_dev_t *dev);
|
||||
#define XHCI_MAX_CONTROLLERS 8u
|
||||
int xhci_find_and_map(xhci_dev_t *dev, unsigned index);
|
||||
|
||||
/*
|
||||
* xhci_bringup — reset the controller, allocate and program the DCBAA,
|
||||
@@ -456,17 +465,15 @@ int xhci_find_and_map(xhci_dev_t *dev);
|
||||
int xhci_bringup(xhci_dev_t *dev);
|
||||
|
||||
/*
|
||||
* xhci_get_dev — return the module-static xhci_dev_t* xhci_poll_events()
|
||||
* itself reads (only one controller is supported), or NULL
|
||||
* if xhci_bringup() has not completed successfully yet.
|
||||
*
|
||||
* Milestone 2h: callers outside this driver (sk_repl_idle(), eventually
|
||||
* the block-subsystem attach glue) have no other way to reach the device
|
||||
* handle -- every earlier caller of this driver's API already had one in
|
||||
* hand (kernel_main.c's own local xhci_dev_t), which doesn't help code
|
||||
* that only runs later, on a hotplug event it wasn't the one to observe.
|
||||
* xhci_dev_count / xhci_dev_at — the controllers xhci_bringup() has
|
||||
* brought up, in the order found: how many, and the i-th
|
||||
* (NULL past the end). Callers outside this driver
|
||||
* (sk_repl_idle(), the block-subsystem attach glue) reach
|
||||
* each controller this way. Replaced xhci_get_dev(), which
|
||||
* returned the one controller there used to be (2026-10-14).
|
||||
*/
|
||||
xhci_dev_t *xhci_get_dev(void);
|
||||
uint32_t xhci_dev_count(void); /* controllers brought up */
|
||||
xhci_dev_t *xhci_dev_at(uint32_t i); /* the i-th, or NULL */
|
||||
|
||||
/*
|
||||
* xhci_msc_slot_for — bounds-checked lookup into dev->msc_slots[slot_id]
|
||||
|
||||
Reference in New Issue
Block a user