+ if (strncmp(gIOSpinDumpKextName, fName, sizeof(gIOSpinDumpKextName)) != 0)
+ return;
+
+ if (gIOSpinDumpDelayType[0] == '\0' &&
+ !(PE_parse_boot_argn("swd_delay_type", &gIOSpinDumpDelayType,
+ sizeof(gIOSpinDumpDelayType))))
+ {
+ strncpy(gIOSpinDumpDelayType, "SetState", sizeof(gIOSpinDumpDelayType));
+ }
+
+ if (strncmp(delay_type, gIOSpinDumpDelayType, sizeof(gIOSpinDumpDelayType)) != 0)
+ return;
+
+ if (gIOSpinDumpDelayDuration == 0 &&
+ !(PE_parse_boot_argn("swd_delay_duration", &gIOSpinDumpDelayDuration,
+ sizeof(gIOSpinDumpDelayDuration))))
+ {
+ gIOSpinDumpDelayDuration = 300;
+ }
+
+ clock_interval_to_deadline(gIOSpinDumpDelayDuration, kMillisecondScale, &deadline);
+
+ retain();
+ pending = thread_call_enter_delayed(fSpinDumpTimer, deadline);
+ if (pending) release();
+}
+
+//*********************************************************************************
+// [private] stop_spindump_timer
+//*********************************************************************************
+
+void IOService::stop_spindump_timer( void )
+{
+ boolean_t pending;
+
+ if (!fSpinDumpTimer || !(kIOKextSpinDump & gIOKitDebug))
+ return;
+
+ pending = thread_call_cancel(fSpinDumpTimer);
+ if (pending) release();
+}
+
+
+//*********************************************************************************
+// [static] actionSpinDumpTimerExpired
+//
+// Inside PM work loop's gate.
+//*********************************************************************************
+
+IOReturn
+IOService::actionSpinDumpTimerExpired(
+ OSObject * target,
+ void * arg0, void * arg1,
+ void * arg2, void * arg3 )
+{
+ getPMRootDomain()->takeStackshot(false, false, true);
+
+ return kIOReturnSuccess;
+}
+
+//*********************************************************************************
+// spindump_timer_expired
+//
+// Thread call function. Holds a retain while the callout is in flight.
+//*********************************************************************************
+
+void
+IOService::spindump_timer_expired( thread_call_param_t arg0, thread_call_param_t arg1 )
+{
+ IOService * me = (IOService *) arg0;
+
+ if (gIOPMWorkLoop)
+ {
+ gIOPMWorkLoop->runAction(&actionSpinDumpTimerExpired, me);
+ }
+ me->release();