fix: RTL-SDR bug fixes and accuracy improvements
This commit is contained in:
@@ -1024,6 +1024,10 @@ namespace Drivers::USB::Xhci {
|
||||
if (slotId == 0 || slotId > MAX_SLOTS || !g_devices[slotId].Active) return;
|
||||
UsbDeviceInfo& dev = g_devices[slotId];
|
||||
if (!dev.BulkInRing || dev.BulkInEpNum == 0) return;
|
||||
// Already armed: priming again would put a second transfer on the ring
|
||||
// for every pool buffer and desync the completion rotation (callbacks
|
||||
// would be handed the wrong buffer). Callers must Stop first.
|
||||
if (g_bulkInPoolCount[slotId] != 0) return;
|
||||
|
||||
if (numBuffers < 1) numBuffers = 1;
|
||||
if (numBuffers > BULK_IN_POOL_MAX) numBuffers = BULK_IN_POOL_MAX;
|
||||
@@ -1060,7 +1064,36 @@ namespace Drivers::USB::Xhci {
|
||||
if (slotId == 0 || slotId > MAX_SLOTS) return;
|
||||
// Disarm the rotation; any late completion now takes the (no-op for SDR)
|
||||
// legacy path and is not re-armed. Buffers are retained for reuse.
|
||||
bool wasArmed = g_bulkInPoolCount[slotId] != 0;
|
||||
g_bulkInPoolCount[slotId] = 0;
|
||||
if (!wasArmed) return;
|
||||
|
||||
// Flush the up-to-PoolCount TRBs still pending on the ring: Stop
|
||||
// Endpoint, then Set TR Dequeue to the enqueue pointer. Without this a
|
||||
// later Start would stack a fresh pool behind the stale TRBs and
|
||||
// overflow the 32-entry transfer ring (16 stale + 16 new > 31 usable),
|
||||
// wrapping the enqueue pointer onto still-pending TRBs.
|
||||
UsbDeviceInfo& dev = g_devices[slotId];
|
||||
if (!dev.Active || dev.BulkInEpNum == 0 || !dev.BulkInRing) return;
|
||||
uint8_t dci = dev.BulkInEpNum * 2 + 1;
|
||||
|
||||
TRB stopTrb = {};
|
||||
stopTrb.Control = (TRB_STOP_ENDPOINT << TRB_TYPE_SHIFT)
|
||||
| ((uint32_t)slotId << 24)
|
||||
| ((uint32_t)dci << 16);
|
||||
SendCommand(stopTrb);
|
||||
|
||||
uint64_t newDeq = dev.BulkInRingPhys
|
||||
+ (uint64_t)dev.BulkInRingEnqueue * sizeof(TRB);
|
||||
if (dev.BulkInRingCCS) newDeq |= 1; // DCS bit
|
||||
|
||||
TRB deqTrb = {};
|
||||
deqTrb.Parameter0 = (uint32_t)(newDeq & 0xFFFFFFFF);
|
||||
deqTrb.Parameter1 = (uint32_t)(newDeq >> 32);
|
||||
deqTrb.Control = (TRB_SET_TR_DEQUEUE << TRB_TYPE_SHIFT)
|
||||
| ((uint32_t)slotId << 24)
|
||||
| ((uint32_t)dci << 16);
|
||||
SendCommand(deqTrb);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user