fix(wifi): unify getWorkLoop with IO80211WorkQueue and add direct kprintf screen logging
- Breakthrough & Root Cause Analysis:
* Persistent NVRAM analysis revealed 'qcom_stage=cb_getWorkQueue' was successfully written before the freeze.
* Disassembly of IO80211Controller::getWorkLoop() revealed that Apple's IO80211Controller directly
aliases getWorkLoop() to getWorkQueue() (jmp *(vptr + 0xc68)).
* QualcommWifi was previously maintaining a distinct fWorkLoop (IOWorkLoop) separate from fWorkQueue (IO80211WorkQueue),
causing cross-workloop lock inversions and deadlocks when Skywalk and CCPipe attempted to synchronize.
- Enhancements:
* Integrated native Darwin kprintf() in logNvramStage() to print diagnostic stages directly onto the
hardware video text console during early boot (bypassing delayed memory-only IOLog buffer).
* Unified getWorkLoop() and createWorkLoop() to use fWorkQueue directly as in Apple's driver.
* Added invocation counter to getWorkQueue() (cb_getWorkQueue_1, cb_getWorkQueue_2) to trace execution progression.
- Validation:
* Recompiled with ./build_wifi.sh.
* 100% verified against kmutil and BootKernelExtensions.kc.
This commit is contained in:
1 parent
e21d212096
commit
e0414a948e
1 file changed
+13
-16
@@ -19,8 +19,11 @@ extern "C" {
|
||||
#include <IOKit/IOPlatformExpert.h>
|
||||
#include <IOKit/IOLocks.h>
|
||||
|
||||
extern "C" void kprintf(const char *format, ...);
|
||||
|
||||
static inline void logNvramStage(const char *tag) {
|
||||
IOLog("QualcommWifi: >>> [STAGE] %s <<<\n", tag);
|
||||
kprintf("QualcommWifi: >>> [STAGE] %s <<<\n", tag);
|
||||
if (tag) {
|
||||
PEWriteNVRAMProperty("qcom_stage", tag, (unsigned int)strlen(tag));
|
||||
}
|
||||
@@ -984,9 +987,14 @@ bool QualcommWifi::createWorkQueue(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sGetWorkQueueCount = 0;
|
||||
|
||||
IO80211WorkQueue* QualcommWifi::getWorkQueue(void) const {
|
||||
logNvramStage("cb_getWorkQueue");
|
||||
IOLog("QualcommWifi: >>> CALLBACK getWorkQueue() -> 0x%p <<<\n", fWorkQueue);
|
||||
sGetWorkQueueCount++;
|
||||
char tag[64];
|
||||
snprintf(tag, sizeof(tag), "cb_getWorkQueue_%d", sGetWorkQueueCount);
|
||||
logNvramStage(tag);
|
||||
IOLog("QualcommWifi: >>> CALLBACK getWorkQueue(#%d) -> 0x%p <<<\n", sGetWorkQueueCount, fWorkQueue);
|
||||
return fWorkQueue;
|
||||
}
|
||||
|
||||
@@ -1005,23 +1013,12 @@ IORecursiveLock* QualcommWifi::allocIO80211RecursiveLock(void) {
|
||||
}
|
||||
|
||||
bool QualcommWifi::createWorkLoop(void) {
|
||||
logNvramStage("createWorkLoop");
|
||||
if (fWorkLoop) {
|
||||
return true;
|
||||
}
|
||||
fWorkLoop = IOWorkLoop::workLoop();
|
||||
if (!fWorkLoop) {
|
||||
logNvramStage("workLoop_alloc_failed");
|
||||
IOLog("QualcommWifi: Erreur - Impossible d'allouer IOWorkLoop !\n");
|
||||
return false;
|
||||
}
|
||||
logNvramStage("workLoop_ok");
|
||||
IOLog("QualcommWifi: IOWorkLoop allouee avec succes (0x%p) !\n", fWorkLoop);
|
||||
return true;
|
||||
logNvramStage("createWorkLoop_alias");
|
||||
return createWorkQueue();
|
||||
}
|
||||
|
||||
IOWorkLoop* QualcommWifi::getWorkLoop(void) const {
|
||||
return fWorkLoop ? fWorkLoop : (getProvider() ? getProvider()->getWorkLoop() : nullptr);
|
||||
return (IOWorkLoop*)fWorkQueue;
|
||||
}
|
||||
|
||||
IOReturn QualcommWifi::getHardwareAddress(IOEthernetAddress *addrP) {
|
||||
|
||||
Reference in new issue
Block a user