wip: async BT firmware download attempt — DO NOT MERGE, breaks AX211 bring-up
Deferring the Intel BT firmware download off the boot path made the AX211 bootloader stop answering after the first FC05; even the final synchronous revert freezes boot, so one of the 'neutral' fixes kept in this diff breaks the bring-up on its own (candidates: BT-TRACE logging inside TransferCallback, unconditional interrupt-IN re-queue after error completions on a halted EP, xHCI interrupt-IN ZLP len fix interacting with HID, InPollContext owner check). Full history + next experiments in memory notes, 2026-07-05/06. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a5eafb4fc
commit
8bf3ceb457
9 files changed
+163
-31
No files matched your search
@@ -428,7 +428,13 @@ namespace Drivers::USB::Xhci {
|
||||
// sent from a Bluetooth event handler). Such callers must fire-and-forget,
|
||||
// not wait, since a nested PollEvents is a no-op.
|
||||
bool InPollContext() {
|
||||
return g_pollActive.load(std::memory_order_relaxed);
|
||||
// Same-core only: "nested under PollEvents" means an event callback on
|
||||
// THIS core issued the query. A different core merely polling must
|
||||
// not make callers (WaitCommandComplete & co.) skip their wait -- that
|
||||
// reported success before the reply arrived (same cross-core bug
|
||||
// ControlTransfer's trueNested check already guards against).
|
||||
return g_pollActive.load(std::memory_order_relaxed) &&
|
||||
g_pollOwnerCpu.load(std::memory_order_relaxed) == CurrentCpuIndex();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -568,9 +574,17 @@ namespace Drivers::USB::Xhci {
|
||||
g_transferCallbacks[slotId](slotId, epDci,
|
||||
nullptr, 0, completionCode);
|
||||
} else if (epDci == intDci) {
|
||||
// Interrupt IN — HID or callback dispatch
|
||||
uint16_t len = dev.InterruptMaxPacket;
|
||||
if (residual < len) len = dev.InterruptMaxPacket - (uint16_t)residual;
|
||||
// Interrupt IN — HID or callback dispatch.
|
||||
// len = actually-transferred bytes. A ZLP has
|
||||
// residual == requested, so len MUST be 0 (same
|
||||
// fix as bulk IN above): the old code left len at
|
||||
// the full max-packet and handed the callback a
|
||||
// slice of STALE DMA buffer -- for Bluetooth that
|
||||
// can replay the PREVIOUS HCI event into the
|
||||
// command-complete mailbox.
|
||||
uint16_t reqLen = dev.InterruptMaxPacket;
|
||||
uint16_t len = (residual < reqLen)
|
||||
? (uint16_t)(reqLen - residual) : 0;
|
||||
|
||||
if (dev.InterfaceClass == UsbDevice::CLASS_HID) {
|
||||
if (dev.InterfaceProtocol == UsbDevice::PROTOCOL_KEYBOARD) {
|
||||
|
||||
Reference in new issue
Block a user