xref: /xnu-8019.80.24/iokit/Kernel/IOServicePM.cpp (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
1 /*
2  * Copyright (c) 1998-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <IOKit/assert.h>
30 #include <IOKit/IOKitDebug.h>
31 #include <IOKit/IOLib.h>
32 #include <IOKit/IOMessage.h>
33 #include <IOKit/IOPlatformExpert.h>
34 #include <IOKit/IOService.h>
35 #include <IOKit/IOUserServer.h>
36 #include <IOKit/IOEventSource.h>
37 #include <IOKit/IOWorkLoop.h>
38 #include <IOKit/IOCommand.h>
39 #include <IOKit/IOTimeStamp.h>
40 #include <IOKit/IOReportMacros.h>
41 #include <IOKit/IODeviceTreeSupport.h>
42 
43 #include <IOKit/pwr_mgt/IOPMlog.h>
44 #include <IOKit/pwr_mgt/IOPMinformee.h>
45 #include <IOKit/pwr_mgt/IOPMinformeeList.h>
46 #include <IOKit/pwr_mgt/IOPowerConnection.h>
47 #include <IOKit/pwr_mgt/RootDomain.h>
48 #include <IOKit/pwr_mgt/IOPMPrivate.h>
49 
50 #include <sys/proc.h>
51 #include <sys/proc_internal.h>
52 #include <sys/sysctl.h>
53 #include <libkern/OSDebug.h>
54 #include <kern/thread.h>
55 
56 // Required for notification instrumentation
57 #include "IOServicePrivate.h"
58 #include "IOServicePMPrivate.h"
59 #include "IOKitKernelInternal.h"
60 
61 #if USE_SETTLE_TIMER
62 static void settle_timer_expired(thread_call_param_t, thread_call_param_t);
63 #endif
64 static void idle_timer_expired(thread_call_param_t, thread_call_param_t);
65 static void tellKernelClientApplier(OSObject * object, void * arg);
66 static void tellAppClientApplier(OSObject * object, void * arg);
67 static const char * getNotificationPhaseString(uint32_t phase);
68 
69 static uint64_t
computeTimeDeltaNS(const AbsoluteTime * start)70 computeTimeDeltaNS( const AbsoluteTime * start )
71 {
72 	AbsoluteTime    now;
73 	uint64_t        nsec;
74 
75 	clock_get_uptime(&now);
76 	SUB_ABSOLUTETIME(&now, start);
77 	absolutetime_to_nanoseconds(now, &nsec);
78 	return nsec;
79 }
80 
81 #if PM_VARS_SUPPORT
82 OSDefineMetaClassAndStructors(IOPMprot, OSObject)
83 #endif
84 
85 //******************************************************************************
86 // Globals
87 //******************************************************************************
88 
89 static bool                  gIOPMInitialized       = false;
90 static uint32_t              gIOPMBusyRequestCount  = 0;
91 static uint32_t              gIOPMWorkInvokeCount   = 0;
92 static uint32_t              gIOPMTickleGeneration  = 0;
93 static IOWorkLoop *          gIOPMWorkLoop          = NULL;
94 static IOPMRequestQueue *    gIOPMRequestQueue      = NULL;
95 static IOPMRequestQueue *    gIOPMReplyQueue        = NULL;
96 static IOPMWorkQueue *       gIOPMWorkQueue         = NULL;
97 static IOPMCompletionQueue * gIOPMCompletionQueue   = NULL;
98 static IOPMRequest *         gIOPMRequest           = NULL;
99 static IOService *           gIOPMRootNode          = NULL;
100 static IOPlatformExpert *    gPlatform              = NULL;
101 
102 // log setPowerStates and powerStateChange longer than (ns):
103 static uint64_t              gIOPMSetPowerStateLogNS =
104 #if defined(__i386__) || defined(__x86_64__)
105     (300ULL * 1000ULL * 1000ULL)
106 #else
107     (50ULL * 1000ULL * 1000ULL)
108 #endif
109 ;
110 
111 const OSSymbol *             gIOPMPowerClientDevice     = NULL;
112 const OSSymbol *             gIOPMPowerClientDriver     = NULL;
113 const OSSymbol *             gIOPMPowerClientChildProxy = NULL;
114 const OSSymbol *             gIOPMPowerClientChildren   = NULL;
115 const OSSymbol *             gIOPMPowerClientRootDomain = NULL;
116 
117 static const OSSymbol *      gIOPMPowerClientAdvisoryTickle = NULL;
118 static bool                  gIOPMAdvisoryTickleEnabled = true;
119 static thread_t              gIOPMWatchDogThread        = NULL;
120 TUNABLE_WRITEABLE(uint32_t, gCanSleepTimeout, "pmtimeout", 0);
121 
122 static uint32_t
getPMRequestType(void)123 getPMRequestType( void )
124 {
125 	uint32_t type = kIOPMRequestTypeInvalid;
126 	if (gIOPMRequest) {
127 		type = gIOPMRequest->getType();
128 	}
129 	return type;
130 }
131 
132 SYSCTL_UINT(_kern, OID_AUTO, pmtimeout, CTLFLAG_RW | CTLFLAG_LOCKED, &gCanSleepTimeout, 0, "Power Management Timeout");
133 
134 //******************************************************************************
135 // Macros
136 //******************************************************************************
137 
138 #define PM_ERROR(x...)              do { kprintf(x);IOLog(x); \
139 	                            } while (false)
140 #define PM_LOG(x...)                do { kprintf(x); } while (false)
141 
142 #define PM_LOG1(x...)               do {  \
143 	                            if (kIOLogDebugPower & gIOKitDebug) \
144 	                                kprintf(x); } while (false)
145 
146 #define PM_LOG2(x...)               do {  \
147 	                            if (kIOLogDebugPower & gIOKitDebug) \
148 	                                kprintf(x); } while (false)
149 
150 #if 0
151 #define PM_LOG3(x...)               do { kprintf(x); } while (false)
152 #else
153 #define PM_LOG3(x...)
154 #endif
155 
156 #define RD_LOG(x...)                do { \
157 	                            if ((kIOLogPMRootDomain & gIOKitDebug) && \
158 	                                (getPMRootDomain() == this)) { \
159 	                                kprintf("PMRD: " x); \
160 	                            }} while (false)
161 #define PM_ASSERT_IN_GATE(x)          \
162 do {                                  \
163     assert(gIOPMWorkLoop->inGate());  \
164 } while(false)
165 
166 #define PM_LOCK()                   IOLockLock(fPMLock)
167 #define PM_UNLOCK()                 IOLockUnlock(fPMLock)
168 #define PM_LOCK_SLEEP(event, dl)    IOLockSleepDeadline(fPMLock, event, dl, THREAD_UNINT)
169 #define PM_LOCK_WAKEUP(event)       IOLockWakeup(fPMLock, event, false)
170 
171 #define us_per_s                    1000000
172 #define ns_per_us                   1000
173 #define k30Seconds                  (30*us_per_s)
174 #define k5Seconds                   ( 5*us_per_s)
175 #if !defined(XNU_TARGET_OS_OSX)
176 #define kCanSleepMaxTimeReq         k5Seconds
177 #else /* defined(XNU_TARGET_OS_OSX) */
178 #define kCanSleepMaxTimeReq         k30Seconds
179 #endif /* defined(XNU_TARGET_OS_OSX) */
180 #define kMaxTimeRequested           k30Seconds
181 #define kMinAckTimeoutTicks         (10*1000000)
182 #define kIOPMTardyAckSPSKey         "IOPMTardyAckSetPowerState"
183 #define kIOPMTardyAckPSCKey         "IOPMTardyAckPowerStateChange"
184 #define kPwrMgtKey                  "IOPowerManagement"
185 
186 #define OUR_PMLog(t, a, b) do {                 \
187     if (pwrMgt) {                               \
188 	if (gIOKitDebug & kIOLogPower)          \
189 	    pwrMgt->pmPrint(t, a, b);           \
190 	if (gIOKitTrace & kIOTracePowerMgmt)    \
191 	    pwrMgt->pmTrace(t, DBG_FUNC_NONE, a, b);        \
192     }                                           \
193     } while(0)
194 
195 #define OUR_PMLogFuncStart(t, a, b) do {        \
196     if (pwrMgt) {                               \
197 	if (gIOKitDebug & kIOLogPower)          \
198 	    pwrMgt->pmPrint(t, a, b);           \
199 	if (gIOKitTrace & kIOTracePowerMgmt)    \
200 	    pwrMgt->pmTrace(t, DBG_FUNC_START, a, b);       \
201     }                                           \
202     } while(0)
203 
204 #define OUR_PMLogFuncEnd(t, a, b) do {          \
205     if (pwrMgt) {                               \
206 	if (gIOKitDebug & kIOLogPower)          \
207 	    pwrMgt->pmPrint(-t, a, b);          \
208 	if (gIOKitTrace & kIOTracePowerMgmt)    \
209 	    pwrMgt->pmTrace(t, DBG_FUNC_END, a, b);        \
210     }                                           \
211     } while(0)
212 
213 #define NS_TO_MS(nsec)              ((int)((nsec) / 1000000ULL))
214 #define NS_TO_US(nsec)              ((int)((nsec) / 1000ULL))
215 
216 #define SUPPORT_IDLE_CANCEL         1
217 
218 #define kIOPMPowerStateMax          0xFFFFFFFF
219 #define kInvalidTicklePowerState    kIOPMPowerStateMax
220 
221 #define kNoTickleCancelWindow       (60ULL * 1000ULL * 1000ULL * 1000ULL)
222 
223 #define IS_PM_ROOT                  (this == gIOPMRootNode)
224 #define IS_ROOT_DOMAIN              (getPMRootDomain() == this)
225 #define IS_POWER_DROP               (StateOrder(fHeadNotePowerState) < StateOrder(fCurrentPowerState))
226 #define IS_POWER_RISE               (StateOrder(fHeadNotePowerState) > StateOrder(fCurrentPowerState))
227 
228 // log app responses longer than (ns):
229 #define LOG_APP_RESPONSE_TIMES      (100ULL * 1000ULL * 1000ULL)
230 // use message tracer to log messages longer than (ns):
231 #define LOG_APP_RESPONSE_MSG_TRACER (3 * 1000ULL * 1000ULL * 1000ULL)
232 
233 // log kext responses longer than (ns):
234 #define LOG_KEXT_RESPONSE_TIMES     (100ULL * 1000ULL * 1000ULL)
235 
236 enum {
237 	kReserveDomainPower = 1
238 };
239 
240 #define MS_PUSH(n)  \
241     do { assert(kIOPM_BadMachineState == fSavedMachineState); \
242 	 assert(kIOPM_BadMachineState != n); \
243 	 fSavedMachineState = n; } while (false)
244 
245 #define MS_POP()    \
246     do { assert(kIOPM_BadMachineState != fSavedMachineState); \
247 	 fMachineState = fSavedMachineState; \
248 	 fSavedMachineState = kIOPM_BadMachineState; } while (false)
249 
250 #define PM_ACTION_TICKLE(a) \
251     do { if (fPMActions.a) { \
252 	 (fPMActions.a)(fPMActions.target, this, &fPMActions); } \
253 	 } while (false)
254 
255 #define PM_ACTION_CHANGE(a, x, y) \
256     do { if (fPMActions.a) { \
257 	 (fPMActions.a)(fPMActions.target, this, &fPMActions, gIOPMRequest, x, y); } \
258 	 } while (false)
259 
260 #define PM_ACTION_CLIENT(a, x, y, z) \
261     do { if (fPMActions.a) { \
262 	 (fPMActions.a)(fPMActions.target, this, &fPMActions, x, y, z); } \
263 	 } while (false)
264 
265 static OSNumber * copyClientIDForNotification(
266 	OSObject *object,
267 	IOPMInterestContext *context);
268 
269 static void logClientIDForNotification(
270 	OSObject *object,
271 	IOPMInterestContext *context,
272 	const char *logString);
273 
274 //*********************************************************************************
275 // PM machine states
276 //
277 // Check kgmacros after modifying machine states.
278 //*********************************************************************************
279 
280 enum {
281 	kIOPM_Finished                                      = 0,
282 
283 	kIOPM_OurChangeTellClientsPowerDown                 = 1,
284 	kIOPM_OurChangeTellUserPMPolicyPowerDown            = 2,
285 	kIOPM_OurChangeTellPriorityClientsPowerDown         = 3,
286 	kIOPM_OurChangeNotifyInterestedDriversWillChange    = 4,
287 	kIOPM_OurChangeSetPowerState                        = 5,
288 	kIOPM_OurChangeWaitForPowerSettle                   = 6,
289 	kIOPM_OurChangeNotifyInterestedDriversDidChange     = 7,
290 	kIOPM_OurChangeTellCapabilityDidChange              = 8,
291 	kIOPM_OurChangeFinish                               = 9,
292 
293 	kIOPM_ParentChangeTellPriorityClientsPowerDown      = 10,
294 	kIOPM_ParentChangeNotifyInterestedDriversWillChange = 11,
295 	kIOPM_ParentChangeSetPowerState                     = 12,
296 	kIOPM_ParentChangeWaitForPowerSettle                = 13,
297 	kIOPM_ParentChangeNotifyInterestedDriversDidChange  = 14,
298 	kIOPM_ParentChangeTellCapabilityDidChange           = 15,
299 	kIOPM_ParentChangeAcknowledgePowerChange            = 16,
300 
301 	kIOPM_NotifyChildrenStart                           = 17,
302 	kIOPM_NotifyChildrenOrdered                         = 18,
303 	kIOPM_NotifyChildrenDelayed                         = 19,
304 	kIOPM_SyncTellClientsPowerDown                      = 20,
305 	kIOPM_SyncTellPriorityClientsPowerDown              = 21,
306 	kIOPM_SyncNotifyWillChange                          = 22,
307 	kIOPM_SyncNotifyDidChange                           = 23,
308 	kIOPM_SyncTellCapabilityDidChange                   = 24,
309 	kIOPM_SyncFinish                                    = 25,
310 	kIOPM_TellCapabilityChangeDone                      = 26,
311 	kIOPM_DriverThreadCallDone                          = 27,
312 
313 	kIOPM_BadMachineState                               = 0xFFFFFFFF
314 };
315 
316 //*********************************************************************************
317 // [public] PMinit
318 //
319 // Initialize power management.
320 //*********************************************************************************
321 
322 void
PMinit(void)323 IOService::PMinit( void )
324 {
325 	if (!initialized) {
326 		if (!gIOPMInitialized) {
327 			gPlatform = getPlatform();
328 			gIOPMWorkLoop = IOWorkLoop::workLoop();
329 			if (gIOPMWorkLoop) {
330 				gIOPMRequestQueue = IOPMRequestQueue::create(
331 					this, OSMemberFunctionCast(IOPMRequestQueue::Action,
332 					this, &IOService::actionPMRequestQueue));
333 
334 				gIOPMReplyQueue = IOPMRequestQueue::create(
335 					this, OSMemberFunctionCast(IOPMRequestQueue::Action,
336 					this, &IOService::actionPMReplyQueue));
337 
338 				gIOPMWorkQueue = IOPMWorkQueue::create(this,
339 				    OSMemberFunctionCast(IOPMWorkQueue::Action, this,
340 				    &IOService::actionPMWorkQueueInvoke),
341 				    OSMemberFunctionCast(IOPMWorkQueue::Action, this,
342 				    &IOService::actionPMWorkQueueRetire));
343 
344 				gIOPMCompletionQueue = IOPMCompletionQueue::create(
345 					this, OSMemberFunctionCast(IOPMCompletionQueue::Action,
346 					this, &IOService::actionPMCompletionQueue));
347 
348 				if (gIOPMWorkLoop->addEventSource(gIOPMRequestQueue) !=
349 				    kIOReturnSuccess) {
350 					gIOPMRequestQueue->release();
351 					gIOPMRequestQueue = NULL;
352 				}
353 
354 				if (gIOPMWorkLoop->addEventSource(gIOPMReplyQueue) !=
355 				    kIOReturnSuccess) {
356 					gIOPMReplyQueue->release();
357 					gIOPMReplyQueue = NULL;
358 				}
359 
360 				if (gIOPMWorkLoop->addEventSource(gIOPMWorkQueue) !=
361 				    kIOReturnSuccess) {
362 					gIOPMWorkQueue->release();
363 					gIOPMWorkQueue = NULL;
364 				}
365 
366 				// Must be added after the work queue, which pushes request
367 				// to the completion queue without signaling the work loop.
368 				if (gIOPMWorkLoop->addEventSource(gIOPMCompletionQueue) !=
369 				    kIOReturnSuccess) {
370 					gIOPMCompletionQueue->release();
371 					gIOPMCompletionQueue = NULL;
372 				}
373 
374 				gIOPMPowerClientDevice =
375 				    OSSymbol::withCStringNoCopy( "DevicePowerState" );
376 
377 				gIOPMPowerClientDriver =
378 				    OSSymbol::withCStringNoCopy( "DriverPowerState" );
379 
380 				gIOPMPowerClientChildProxy =
381 				    OSSymbol::withCStringNoCopy( "ChildProxyPowerState" );
382 
383 				gIOPMPowerClientChildren =
384 				    OSSymbol::withCStringNoCopy( "ChildrenPowerState" );
385 
386 				gIOPMPowerClientAdvisoryTickle =
387 				    OSSymbol::withCStringNoCopy( "AdvisoryTicklePowerState" );
388 
389 				gIOPMPowerClientRootDomain =
390 				    OSSymbol::withCStringNoCopy( "RootDomainPower" );
391 			}
392 
393 			if (gIOPMRequestQueue && gIOPMReplyQueue && gIOPMCompletionQueue) {
394 				gIOPMInitialized = true;
395 			}
396 
397 #if (DEVELOPMENT || DEBUG)
398 			uint32_t setPowerStateLogMS = 0;
399 			if (PE_parse_boot_argn("setpowerstate_log", &setPowerStateLogMS, sizeof(setPowerStateLogMS))) {
400 				gIOPMSetPowerStateLogNS = setPowerStateLogMS * 1000000ULL;
401 			}
402 #endif
403 		}
404 		if (!gIOPMInitialized) {
405 			return;
406 		}
407 
408 		pwrMgt = new IOServicePM;
409 		pwrMgt->init();
410 		setProperty(kPwrMgtKey, pwrMgt);
411 
412 		queue_init(&pwrMgt->WorkChain);
413 		queue_init(&pwrMgt->RequestHead);
414 		queue_init(&pwrMgt->PMDriverCallQueue);
415 
416 		fOwner                      = this;
417 		fPMLock                     = IOLockAlloc();
418 		fInterestedDrivers          = new IOPMinformeeList;
419 		fInterestedDrivers->initialize();
420 		fDesiredPowerState          = kPowerStateZero;
421 		fDeviceDesire               = kPowerStateZero;
422 		fInitialPowerChange         = true;
423 		fInitialSetPowerState       = true;
424 		fPreviousRequestPowerFlags  = 0;
425 		fDeviceOverrideEnabled      = false;
426 		fMachineState               = kIOPM_Finished;
427 		fSavedMachineState          = kIOPM_BadMachineState;
428 		fIdleTimerMinPowerState     = kPowerStateZero;
429 		fActivityLock               = IOLockAlloc();
430 		fStrictTreeOrder            = false;
431 		fActivityTicklePowerState   = kInvalidTicklePowerState;
432 		fAdvisoryTicklePowerState   = kInvalidTicklePowerState;
433 		fControllingDriver          = NULL;
434 		fPowerStates                = NULL;
435 		fNumberOfPowerStates        = 0;
436 		fCurrentPowerState          = kPowerStateZero;
437 		fParentsCurrentPowerFlags   = 0;
438 		fMaxPowerState              = kPowerStateZero;
439 		fName                       = getName();
440 		fParentsKnowState           = false;
441 		fSerialNumber               = 0;
442 		fResponseArray              = NULL;
443 		fNotifyClientArray          = NULL;
444 		fCurrentPowerConsumption    = kIOPMUnknown;
445 		fOverrideMaxPowerState      = kIOPMPowerStateMax;
446 
447 		if (!gIOPMRootNode && (getParentEntry(gIOPowerPlane) == getRegistryRoot())) {
448 			gIOPMRootNode = this;
449 			fParentsKnowState = true;
450 		} else if (getProperty(kIOPMResetPowerStateOnWakeKey) == kOSBooleanTrue) {
451 			fResetPowerStateOnWake = true;
452 		}
453 
454 		if (IS_ROOT_DOMAIN) {
455 			fWatchdogTimer = thread_call_allocate(
456 				&IOService::watchdog_timer_expired, (thread_call_param_t)this);
457 			fWatchdogLock = IOLockAlloc();
458 
459 			fBlockedArray =  OSArray::withCapacity(4);
460 		}
461 
462 		fAckTimer = thread_call_allocate(
463 			&IOService::ack_timer_expired, (thread_call_param_t)this);
464 #if USE_SETTLE_TIMER
465 		fSettleTimer = thread_call_allocate(
466 			&settle_timer_expired, (thread_call_param_t)this);
467 #endif
468 		fIdleTimer = thread_call_allocate(
469 			&idle_timer_expired, (thread_call_param_t)this);
470 		fDriverCallEntry = thread_call_allocate(
471 			(thread_call_func_t) &IOService::pmDriverCallout, this);
472 		assert(fDriverCallEntry);
473 
474 		// Check for powerChangeDone override.
475 		if (OSMemberFunctionCast(void (*)(void),
476 		    getResourceService(), &IOService::powerChangeDone) !=
477 		    OSMemberFunctionCast(void (*)(void),
478 		    this, &IOService::powerChangeDone)) {
479 			fPCDFunctionOverride = true;
480 		}
481 
482 #if PM_VARS_SUPPORT
483 		IOPMprot * prot = new IOPMprot;
484 		if (prot) {
485 			prot->init();
486 			prot->ourName = fName;
487 			prot->thePlatform = gPlatform;
488 			fPMVars = prot;
489 			pm_vars = prot;
490 		}
491 #else
492 		pm_vars = (void *) (uintptr_t) true;
493 #endif
494 
495 		initialized = true;
496 	}
497 }
498 
499 //*********************************************************************************
500 // [private] PMfree
501 //
502 // Free the data created by PMinit. Only called from IOService::free().
503 //*********************************************************************************
504 
505 void
PMfree(void)506 IOService::PMfree( void )
507 {
508 	initialized = false;
509 	pm_vars = NULL;
510 
511 	if (pwrMgt) {
512 		assert(fMachineState == kIOPM_Finished);
513 		assert(fInsertInterestSet == NULL);
514 		assert(fRemoveInterestSet == NULL);
515 		assert(fNotifyChildArray == NULL);
516 		assert(queue_empty(&pwrMgt->RequestHead));
517 		assert(queue_empty(&fPMDriverCallQueue));
518 
519 		if (fWatchdogTimer) {
520 			thread_call_cancel(fWatchdogTimer);
521 			thread_call_free(fWatchdogTimer);
522 			fWatchdogTimer = NULL;
523 		}
524 
525 		if (fWatchdogLock) {
526 			IOLockFree(fWatchdogLock);
527 			fWatchdogLock = NULL;
528 		}
529 
530 		if (fBlockedArray) {
531 			fBlockedArray->release();
532 			fBlockedArray = NULL;
533 		}
534 #if USE_SETTLE_TIMER
535 		if (fSettleTimer) {
536 			thread_call_cancel(fSettleTimer);
537 			thread_call_free(fSettleTimer);
538 			fSettleTimer = NULL;
539 		}
540 #endif
541 		if (fAckTimer) {
542 			thread_call_cancel(fAckTimer);
543 			thread_call_free(fAckTimer);
544 			fAckTimer = NULL;
545 		}
546 		if (fIdleTimer) {
547 			thread_call_cancel(fIdleTimer);
548 			thread_call_free(fIdleTimer);
549 			fIdleTimer = NULL;
550 		}
551 		if (fDriverCallEntry) {
552 			thread_call_free(fDriverCallEntry);
553 			fDriverCallEntry = NULL;
554 		}
555 		if (fPMLock) {
556 			IOLockFree(fPMLock);
557 			fPMLock = NULL;
558 		}
559 		if (fActivityLock) {
560 			IOLockFree(fActivityLock);
561 			fActivityLock = NULL;
562 		}
563 		if (fInterestedDrivers) {
564 			fInterestedDrivers->release();
565 			fInterestedDrivers = NULL;
566 		}
567 		if (fDriverCallParamSlots && fDriverCallParamPtr) {
568 			IODelete(fDriverCallParamPtr, DriverCallParam, fDriverCallParamSlots);
569 			fDriverCallParamPtr = NULL;
570 			fDriverCallParamSlots = 0;
571 		}
572 		if (fResponseArray) {
573 			fResponseArray->release();
574 			fResponseArray = NULL;
575 		}
576 		if (fNotifyClientArray) {
577 			fNotifyClientArray->release();
578 			fNotifyClientArray = NULL;
579 		}
580 		if (fReportBuf && fNumberOfPowerStates) {
581 			IOFreeData(fReportBuf, STATEREPORT_BUFSIZE(fNumberOfPowerStates));
582 			fReportBuf = NULL;
583 		}
584 		if (fPowerStates && fNumberOfPowerStates) {
585 			IODeleteData(fPowerStates, IOPMPSEntry, fNumberOfPowerStates);
586 			fNumberOfPowerStates = 0;
587 			fPowerStates = NULL;
588 		}
589 		if (fPowerClients) {
590 			fPowerClients->release();
591 			fPowerClients = NULL;
592 		}
593 
594 #if PM_VARS_SUPPORT
595 		if (fPMVars) {
596 			fPMVars->release();
597 			fPMVars = NULL;
598 		}
599 #endif
600 
601 		pwrMgt->release();
602 		pwrMgt = NULL;
603 	}
604 }
605 
606 void
PMDebug(uint32_t event,uintptr_t param1,uintptr_t param2)607 IOService::PMDebug( uint32_t event, uintptr_t param1, uintptr_t param2 )
608 {
609 	OUR_PMLog(event, param1, param2);
610 }
611 
612 //*********************************************************************************
613 // [public] joinPMtree
614 //
615 // A policy-maker calls its nub here when initializing, to be attached into
616 // the power management hierarchy.  The default function is to call the
617 // platform expert, which knows how to do it.  This method is overridden
618 // by a nub subclass which may either know how to do it, or may need to
619 // take other action.
620 //
621 // This may be the only "power management" method used in a nub,
622 // meaning it may not be initialized for power management.
623 //*********************************************************************************
624 
625 void
joinPMtree(IOService * driver)626 IOService::joinPMtree( IOService * driver )
627 {
628 	IOPlatformExpert *  platform;
629 
630 	platform = getPlatform();
631 	assert(platform != NULL);
632 	platform->PMRegisterDevice(this, driver);
633 }
634 
635 #ifndef __LP64__
636 //*********************************************************************************
637 // [deprecated] youAreRoot
638 //
639 // Power Managment is informing us that we are the root power domain.
640 //*********************************************************************************
641 
642 IOReturn
youAreRoot(void)643 IOService::youAreRoot( void )
644 {
645 	return IOPMNoErr;
646 }
647 #endif /* !__LP64__ */
648 
649 //*********************************************************************************
650 // [public] PMstop
651 //
652 // Immediately stop driver callouts. Schedule an async stop request to detach
653 // from power plane.
654 //*********************************************************************************
655 
656 void
PMstop(void)657 IOService::PMstop( void )
658 {
659 	IOPMRequest * request;
660 
661 	if (!initialized) {
662 		return;
663 	}
664 
665 	PM_LOCK();
666 
667 	if (fLockedFlags.PMStop) {
668 		PM_LOG2("%s: PMstop() already stopped\n", fName);
669 		PM_UNLOCK();
670 		return;
671 	}
672 
673 	// Inhibit future driver calls.
674 	fLockedFlags.PMStop = true;
675 
676 	// Wait for all prior driver calls to finish.
677 	waitForPMDriverCall();
678 
679 	PM_UNLOCK();
680 
681 	// The rest of the work is performed async.
682 	request = acquirePMRequest( this, kIOPMRequestTypePMStop );
683 	if (request) {
684 		PM_LOG2("%s: %p PMstop\n", getName(), OBFUSCATE(this));
685 		submitPMRequest( request );
686 	}
687 }
688 
689 //*********************************************************************************
690 // [private] handlePMstop
691 //
692 // Disconnect the node from all parents and children in the power plane.
693 //*********************************************************************************
694 
695 void
handlePMstop(IOPMRequest * request)696 IOService::handlePMstop( IOPMRequest * request )
697 {
698 	OSIterator *        iter;
699 	OSObject *          next;
700 	IOPowerConnection * connection;
701 	IOService *         theChild;
702 	IOService *         theParent;
703 
704 	PM_ASSERT_IN_GATE();
705 	PM_LOG2("%s: %p %s start\n", getName(), OBFUSCATE(this), __FUNCTION__);
706 
707 	// remove driver from prevent system sleep lists
708 	getPMRootDomain()->updatePreventIdleSleepList(this, false);
709 	getPMRootDomain()->updatePreventSystemSleepList(this, false);
710 
711 	// remove the property
712 	removeProperty(kPwrMgtKey);
713 
714 	// detach parents
715 	iter = getParentIterator(gIOPowerPlane);
716 	if (iter) {
717 		while ((next = iter->getNextObject())) {
718 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
719 				theParent = (IOService *)connection->copyParentEntry(gIOPowerPlane);
720 				if (theParent) {
721 					theParent->removePowerChild(connection);
722 					theParent->release();
723 				}
724 			}
725 		}
726 		iter->release();
727 	}
728 
729 	// detach IOConnections
730 	detachAbove( gIOPowerPlane );
731 
732 	// no more power state changes
733 	fParentsKnowState = false;
734 
735 	// detach children
736 	iter = getChildIterator(gIOPowerPlane);
737 	if (iter) {
738 		while ((next = iter->getNextObject())) {
739 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
740 				theChild = ((IOService *)(connection->copyChildEntry(gIOPowerPlane)));
741 				if (theChild) {
742 					// detach nub from child
743 					connection->detachFromChild(theChild, gIOPowerPlane);
744 					theChild->release();
745 				}
746 				// detach us from nub
747 				detachFromChild(connection, gIOPowerPlane);
748 			}
749 		}
750 		iter->release();
751 	}
752 
753 	// Remove all interested drivers from the list, including the power
754 	// controlling driver.
755 	//
756 	// Usually, the controlling driver and the policy-maker functionality
757 	// are implemented by the same object, and without the deregistration,
758 	// the object will be holding an extra retain on itself, and cannot
759 	// be freed.
760 
761 	if (fInterestedDrivers) {
762 		IOPMinformeeList *  list = fInterestedDrivers;
763 		IOPMinformee *      item;
764 
765 		PM_LOCK();
766 		while ((item = list->firstInList())) {
767 			list->removeFromList(item->whatObject);
768 		}
769 		PM_UNLOCK();
770 	}
771 
772 	// Clear idle period to prevent idleTimerExpired() from servicing
773 	// idle timer expirations.
774 
775 	fIdleTimerPeriod = 0;
776 	if (fIdleTimer && thread_call_cancel(fIdleTimer)) {
777 		release();
778 	}
779 
780 	PM_LOG2("%s: %p %s done\n", getName(), OBFUSCATE(this), __FUNCTION__);
781 }
782 
783 //*********************************************************************************
784 // [public] addPowerChild
785 //
786 // Power Management is informing us who our children are.
787 //*********************************************************************************
788 
789 IOReturn
addPowerChild(IOService * child)790 IOService::addPowerChild( IOService * child )
791 {
792 	IOPowerConnection * connection  = NULL;
793 	IOPMRequest *       requests[3] = {NULL, NULL, NULL};
794 	OSIterator *        iter;
795 	bool                ok = true;
796 
797 	if (!child) {
798 		return kIOReturnBadArgument;
799 	}
800 
801 	if (!initialized || !child->initialized) {
802 		return IOPMNotYetInitialized;
803 	}
804 
805 	OUR_PMLog( kPMLogAddChild, (uintptr_t) child, 0 );
806 
807 	do {
808 		// Is this child already one of our children?
809 
810 		iter = child->getParentIterator( gIOPowerPlane );
811 		if (iter) {
812 			IORegistryEntry *   entry;
813 			OSObject *          next;
814 
815 			while ((next = iter->getNextObject())) {
816 				if ((entry = OSDynamicCast(IORegistryEntry, next)) &&
817 				    isChild(entry, gIOPowerPlane)) {
818 					ok = false;
819 					break;
820 				}
821 			}
822 			iter->release();
823 		}
824 		if (!ok) {
825 			PM_LOG2("%s: %s (%p) is already a child\n",
826 			    getName(), child->getName(), OBFUSCATE(child));
827 			break;
828 		}
829 
830 		// Add the child to the power plane immediately, but the
831 		// joining connection is marked as not ready.
832 		// We want the child to appear in the power plane before
833 		// returning to the caller, but don't want the caller to
834 		// block on the PM work loop.
835 
836 		connection = new IOPowerConnection;
837 		if (!connection) {
838 			break;
839 		}
840 
841 		// Create a chain of PM requests to perform the bottom-half
842 		// work from the PM work loop.
843 
844 		requests[0] = acquirePMRequest(
845 			/* target */ this,
846 			/* type */ kIOPMRequestTypeAddPowerChild1 );
847 
848 		requests[1] = acquirePMRequest(
849 			/* target */ child,
850 			/* type */ kIOPMRequestTypeAddPowerChild2 );
851 
852 		requests[2] = acquirePMRequest(
853 			/* target */ this,
854 			/* type */ kIOPMRequestTypeAddPowerChild3 );
855 
856 		if (!requests[0] || !requests[1] || !requests[2]) {
857 			break;
858 		}
859 
860 		requests[0]->attachNextRequest( requests[1] );
861 		requests[1]->attachNextRequest( requests[2] );
862 
863 		connection->init();
864 		connection->start(this);
865 		connection->setAwaitingAck(false);
866 		connection->setReadyFlag(false);
867 
868 		attachToChild( connection, gIOPowerPlane );
869 		connection->attachToChild( child, gIOPowerPlane );
870 
871 		// connection needs to be released
872 		requests[0]->fArg0 = connection;
873 		requests[1]->fArg0 = connection;
874 		requests[2]->fArg0 = connection;
875 
876 		submitPMRequests( requests, 3 );
877 		return kIOReturnSuccess;
878 	}while (false);
879 
880 	if (connection) {
881 		connection->release();
882 	}
883 	if (requests[0]) {
884 		releasePMRequest(requests[0]);
885 	}
886 	if (requests[1]) {
887 		releasePMRequest(requests[1]);
888 	}
889 	if (requests[2]) {
890 		releasePMRequest(requests[2]);
891 	}
892 
893 	// Silent failure, to prevent platform drivers from adding the child
894 	// to the root domain.
895 
896 	return kIOReturnSuccess;
897 }
898 
899 //*********************************************************************************
900 // [private] addPowerChild1
901 //
902 // Step 1/3 of adding a power child. Called on the power parent.
903 //*********************************************************************************
904 
905 void
addPowerChild1(IOPMRequest * request)906 IOService::addPowerChild1( IOPMRequest * request )
907 {
908 	IOPMPowerStateIndex tempDesire = kPowerStateZero;
909 
910 	// Make us temporary usable before adding the child.
911 
912 	PM_ASSERT_IN_GATE();
913 	OUR_PMLog( kPMLogMakeUsable, kPMLogMakeUsable, 0 );
914 
915 	if (fControllingDriver && inPlane(gIOPowerPlane) && fParentsKnowState) {
916 		tempDesire = fHighestPowerState;
917 	}
918 
919 	if ((tempDesire != kPowerStateZero) &&
920 	    (IS_PM_ROOT || (StateOrder(fMaxPowerState) >= StateOrder(tempDesire)))) {
921 		adjustPowerState(tempDesire);
922 	}
923 }
924 
925 //*********************************************************************************
926 // [private] addPowerChild2
927 //
928 // Step 2/3 of adding a power child. Called on the joining child.
929 // Execution blocked behind addPowerChild1.
930 //*********************************************************************************
931 
932 void
addPowerChild2(IOPMRequest * request)933 IOService::addPowerChild2( IOPMRequest * request )
934 {
935 	IOPowerConnection * connection = (IOPowerConnection *) request->fArg0;
936 	IOService *         parent;
937 	IOPMPowerFlags      powerFlags;
938 	bool                knowsState;
939 	IOPMPowerStateIndex powerState;
940 	IOPMPowerStateIndex tempDesire;
941 
942 	PM_ASSERT_IN_GATE();
943 	parent = (IOService *) connection->getParentEntry(gIOPowerPlane);
944 
945 	if (!parent || !inPlane(gIOPowerPlane)) {
946 		PM_LOG("%s: addPowerChild2 not in power plane\n", getName());
947 		return;
948 	}
949 
950 	// Parent will be waiting for us to complete this stage.
951 	// It is safe to directly access parent's vars.
952 
953 	knowsState = (parent->fPowerStates) && (parent->fParentsKnowState);
954 	powerState = parent->fCurrentPowerState;
955 
956 	if (knowsState) {
957 		powerFlags = parent->fPowerStates[powerState].outputPowerFlags;
958 	} else {
959 		powerFlags = 0;
960 	}
961 
962 	// Set our power parent.
963 
964 	OUR_PMLog(kPMLogSetParent, knowsState, powerFlags);
965 
966 	setParentInfo( powerFlags, connection, knowsState );
967 
968 	connection->setReadyFlag(true);
969 
970 	if (fControllingDriver && fParentsKnowState) {
971 		fMaxPowerState = fControllingDriver->maxCapabilityForDomainState(fParentsCurrentPowerFlags);
972 		// initially change into the state we are already in
973 		tempDesire = fControllingDriver->initialPowerStateForDomainState(fParentsCurrentPowerFlags);
974 		fPreviousRequestPowerFlags = (IOPMPowerFlags)(-1);
975 		adjustPowerState(tempDesire);
976 	}
977 }
978 
979 //*********************************************************************************
980 // [private] addPowerChild3
981 //
982 // Step 3/3 of adding a power child. Called on the parent.
983 // Execution blocked behind addPowerChild2.
984 //*********************************************************************************
985 
986 void
addPowerChild3(IOPMRequest * request)987 IOService::addPowerChild3( IOPMRequest * request )
988 {
989 	IOPowerConnection * connection = (IOPowerConnection *) request->fArg0;
990 	IOService *         child;
991 	IOPMrootDomain *    rootDomain = getPMRootDomain();
992 
993 	PM_ASSERT_IN_GATE();
994 	child = (IOService *) connection->getChildEntry(gIOPowerPlane);
995 
996 	if (child && inPlane(gIOPowerPlane)) {
997 		if ((this != rootDomain) && child->getProperty("IOPMStrictTreeOrder")) {
998 			PM_LOG1("%s: strict PM order enforced\n", getName());
999 			fStrictTreeOrder = true;
1000 		}
1001 
1002 		if (rootDomain) {
1003 			rootDomain->joinAggressiveness( child );
1004 		}
1005 	} else {
1006 		PM_LOG("%s: addPowerChild3 not in power plane\n", getName());
1007 	}
1008 
1009 	connection->release();
1010 }
1011 
1012 #ifndef __LP64__
1013 //*********************************************************************************
1014 // [deprecated] setPowerParent
1015 //
1016 // Power Management is informing us who our parent is.
1017 // If we have a controlling driver, find out, given our newly-informed
1018 // power domain state, what state it would be in, and then tell it
1019 // to assume that state.
1020 //*********************************************************************************
1021 
1022 IOReturn
setPowerParent(IOPowerConnection * theParent,bool stateKnown,IOPMPowerFlags powerFlags)1023 IOService::setPowerParent(
1024 	IOPowerConnection * theParent, bool stateKnown, IOPMPowerFlags powerFlags )
1025 {
1026 	return kIOReturnUnsupported;
1027 }
1028 #endif /* !__LP64__ */
1029 
1030 //*********************************************************************************
1031 // [public] removePowerChild
1032 //
1033 // Called on a parent whose child is being removed by PMstop().
1034 //*********************************************************************************
1035 
1036 IOReturn
removePowerChild(IOPowerConnection * theNub)1037 IOService::removePowerChild( IOPowerConnection * theNub )
1038 {
1039 	IORegistryEntry *   theChild;
1040 
1041 	PM_ASSERT_IN_GATE();
1042 	OUR_PMLog( kPMLogRemoveChild, 0, 0 );
1043 
1044 	theNub->retain();
1045 
1046 	// detach nub from child
1047 	theChild = theNub->copyChildEntry(gIOPowerPlane);
1048 	if (theChild) {
1049 		theNub->detachFromChild(theChild, gIOPowerPlane);
1050 		theChild->release();
1051 	}
1052 	// detach from the nub
1053 	detachFromChild(theNub, gIOPowerPlane);
1054 
1055 	// Are we awaiting an ack from this child?
1056 	if (theNub->getAwaitingAck()) {
1057 		// yes, pretend we got one
1058 		theNub->setAwaitingAck(false);
1059 		if (fHeadNotePendingAcks != 0) {
1060 			// that's one fewer ack to worry about
1061 			fHeadNotePendingAcks--;
1062 
1063 			// is that the last?
1064 			if (fHeadNotePendingAcks == 0) {
1065 				stop_ack_timer();
1066 				getPMRootDomain()->reset_watchdog_timer(this, 0);
1067 
1068 				// This parent may have a request in the work queue that is
1069 				// blocked on fHeadNotePendingAcks=0. And removePowerChild()
1070 				// is called while executing the child's PMstop request so they
1071 				// can occur simultaneously. IOPMWorkQueue::checkForWork() must
1072 				// restart and check all request queues again.
1073 
1074 				gIOPMWorkQueue->incrementProducerCount();
1075 			}
1076 		}
1077 	}
1078 
1079 	theNub->release();
1080 
1081 	// A child has gone away, re-scan children desires and clamp bits.
1082 	// The fPendingAdjustPowerRequest helps to reduce redundant parent work.
1083 
1084 	if (!fAdjustPowerScheduled) {
1085 		IOPMRequest * request;
1086 		request = acquirePMRequest( this, kIOPMRequestTypeAdjustPowerState );
1087 		if (request) {
1088 			submitPMRequest( request );
1089 			fAdjustPowerScheduled = true;
1090 		}
1091 	}
1092 
1093 	return IOPMNoErr;
1094 }
1095 
1096 //*********************************************************************************
1097 // [public] registerPowerDriver
1098 //
1099 // A driver has called us volunteering to control power to our device.
1100 //*********************************************************************************
1101 
1102 IOReturn
registerPowerDriver(IOService * powerDriver,IOPMPowerState * powerStates,unsigned long numberOfStates)1103 IOService::registerPowerDriver(
1104 	IOService *         powerDriver,
1105 	IOPMPowerState *    powerStates,
1106 	unsigned long       numberOfStates )
1107 {
1108 	IOPMRequest *       request;
1109 	IOPMPSEntry *       powerStatesCopy = NULL;
1110 	IOPMPowerStateIndex stateOrder;
1111 	IOReturn            error = kIOReturnSuccess;
1112 
1113 	if (!initialized) {
1114 		return IOPMNotYetInitialized;
1115 	}
1116 
1117 	if (!powerStates || (numberOfStates < 2)) {
1118 		OUR_PMLog(kPMLogControllingDriverErr5, numberOfStates, 0);
1119 		return kIOReturnBadArgument;
1120 	}
1121 
1122 	if (!powerDriver || !powerDriver->initialized) {
1123 		OUR_PMLog(kPMLogControllingDriverErr4, 0, 0);
1124 		return kIOReturnBadArgument;
1125 	}
1126 
1127 	if (powerStates[0].version > kIOPMPowerStateVersion2) {
1128 		OUR_PMLog(kPMLogControllingDriverErr1, powerStates[0].version, 0);
1129 		return kIOReturnBadArgument;
1130 	}
1131 
1132 	do {
1133 		// Make a copy of the supplied power state array.
1134 		powerStatesCopy = IONewData(IOPMPSEntry, numberOfStates);
1135 		if (!powerStatesCopy) {
1136 			error = kIOReturnNoMemory;
1137 			break;
1138 		}
1139 
1140 		// Initialize to bogus values
1141 		for (IOPMPowerStateIndex i = 0; i < numberOfStates; i++) {
1142 			powerStatesCopy[i].stateOrderToIndex = kIOPMPowerStateMax;
1143 		}
1144 
1145 		for (uint32_t i = 0; i < numberOfStates; i++) {
1146 			powerStatesCopy[i].capabilityFlags  = powerStates[i].capabilityFlags;
1147 			powerStatesCopy[i].outputPowerFlags = powerStates[i].outputPowerCharacter;
1148 			powerStatesCopy[i].inputPowerFlags  = powerStates[i].inputPowerRequirement;
1149 			powerStatesCopy[i].staticPower      = powerStates[i].staticPower;
1150 #if USE_SETTLE_TIMER
1151 			powerStatesCopy[i].settleUpTime     = powerStates[i].settleUpTime;
1152 			powerStatesCopy[i].settleDownTime   = powerStates[i].settleDownTime;
1153 #endif
1154 			if (powerStates[i].version >= kIOPMPowerStateVersion2) {
1155 				stateOrder = powerStates[i].stateOrder;
1156 			} else {
1157 				stateOrder = i;
1158 			}
1159 
1160 			if (stateOrder < numberOfStates) {
1161 				powerStatesCopy[i].stateOrder = stateOrder;
1162 				powerStatesCopy[stateOrder].stateOrderToIndex = i;
1163 			}
1164 		}
1165 
1166 		for (IOPMPowerStateIndex i = 0; i < numberOfStates; i++) {
1167 			if (powerStatesCopy[i].stateOrderToIndex == kIOPMPowerStateMax) {
1168 				// power state order missing
1169 				error = kIOReturnBadArgument;
1170 				break;
1171 			}
1172 		}
1173 		if (kIOReturnSuccess != error) {
1174 			break;
1175 		}
1176 
1177 		request = acquirePMRequest( this, kIOPMRequestTypeRegisterPowerDriver );
1178 		if (!request) {
1179 			error = kIOReturnNoMemory;
1180 			break;
1181 		}
1182 
1183 		powerDriver->retain();
1184 		request->fArg0 = (void *) powerDriver;
1185 		request->fArg1 = (void *) powerStatesCopy;
1186 		request->fArg2 = (void *) numberOfStates;
1187 
1188 		submitPMRequest( request );
1189 		return kIOReturnSuccess;
1190 	}while (false);
1191 
1192 	if (powerStatesCopy) {
1193 		IODeleteData(powerStatesCopy, IOPMPSEntry, numberOfStates);
1194 	}
1195 
1196 	return error;
1197 }
1198 
1199 //*********************************************************************************
1200 // [private] handleRegisterPowerDriver
1201 //*********************************************************************************
1202 
1203 void
handleRegisterPowerDriver(IOPMRequest * request)1204 IOService::handleRegisterPowerDriver( IOPMRequest * request )
1205 {
1206 	IOService *           powerDriver    = (IOService *)   request->fArg0;
1207 	IOPMPSEntry *         powerStates    = (IOPMPSEntry *) request->fArg1;
1208 	IOPMPowerStateIndex   numberOfStates = (IOPMPowerStateIndex) request->fArg2;
1209 	IOPMPowerStateIndex   i, stateIndex;
1210 	IOPMPowerStateIndex   lowestPowerState;
1211 	IOService *           root;
1212 	OSIterator *          iter;
1213 
1214 	PM_ASSERT_IN_GATE();
1215 	assert(powerStates);
1216 	assert(powerDriver);
1217 	assert(numberOfStates > 1);
1218 
1219 	if (!fNumberOfPowerStates) {
1220 		OUR_PMLog(kPMLogControllingDriver, numberOfStates, kIOPMPowerStateVersion1);
1221 
1222 		fPowerStates            = powerStates;
1223 		fNumberOfPowerStates    = numberOfStates;
1224 		fControllingDriver      = powerDriver;
1225 		fCurrentCapabilityFlags = fPowerStates[0].capabilityFlags;
1226 
1227 		lowestPowerState   = fPowerStates[0].stateOrderToIndex;
1228 		fHighestPowerState = fPowerStates[numberOfStates - 1].stateOrderToIndex;
1229 
1230 		{
1231 			uint32_t        aotFlags;
1232 			IOService *     service;
1233 			OSObject *      object;
1234 			OSData *        data;
1235 
1236 			// Disallow kIOPMAOTPower states unless device tree enabled
1237 
1238 			aotFlags = 0;
1239 			service  = this;
1240 			while (service && !service->inPlane(gIODTPlane)) {
1241 				service = service->getProvider();
1242 			}
1243 			if (service) {
1244 				object = service->copyProperty(kIOPMAOTPowerKey, gIODTPlane);
1245 				data = OSDynamicCast(OSData, object);
1246 				if (data && (data->getLength() >= sizeof(uint32_t))) {
1247 					aotFlags = ((uint32_t *)data->getBytesNoCopy())[0];
1248 				}
1249 				OSSafeReleaseNULL(object);
1250 			}
1251 			if (!aotFlags) {
1252 				for (i = 0; i < numberOfStates; i++) {
1253 					if (kIOPMAOTPower & fPowerStates[i].inputPowerFlags) {
1254 						fPowerStates[i].inputPowerFlags  = 0xFFFFFFFF;
1255 						fPowerStates[i].capabilityFlags  = 0;
1256 						fPowerStates[i].outputPowerFlags = 0;
1257 					}
1258 				}
1259 			}
1260 		}
1261 
1262 		// OR'in all the output power flags
1263 		fMergedOutputPowerFlags = 0;
1264 		fDeviceUsablePowerState = lowestPowerState;
1265 		for (i = 0; i < numberOfStates; i++) {
1266 			fMergedOutputPowerFlags |= fPowerStates[i].outputPowerFlags;
1267 
1268 			stateIndex = fPowerStates[i].stateOrderToIndex;
1269 			assert(stateIndex < numberOfStates);
1270 			if ((fDeviceUsablePowerState == lowestPowerState) &&
1271 			    (fPowerStates[stateIndex].capabilityFlags & IOPMDeviceUsable)) {
1272 				// The minimum power state that the device is usable
1273 				fDeviceUsablePowerState = stateIndex;
1274 			}
1275 		}
1276 
1277 		// Register powerDriver as interested, unless already done.
1278 		// We don't want to register the default implementation since
1279 		// it does nothing. One ramification of not always registering
1280 		// is the one fewer retain count held.
1281 
1282 		root = getPlatform()->getProvider();
1283 		assert(root);
1284 		if (!root ||
1285 		    ((OSMemberFunctionCast(void (*)(void),
1286 		    root, &IOService::powerStateDidChangeTo)) !=
1287 		    ((OSMemberFunctionCast(void (*)(void),
1288 		    this, &IOService::powerStateDidChangeTo)))) ||
1289 		    ((OSMemberFunctionCast(void (*)(void),
1290 		    root, &IOService::powerStateWillChangeTo)) !=
1291 		    ((OSMemberFunctionCast(void (*)(void),
1292 		    this, &IOService::powerStateWillChangeTo))))) {
1293 			if (fInterestedDrivers->findItem(powerDriver) == NULL) {
1294 				PM_LOCK();
1295 				fInterestedDrivers->appendNewInformee(powerDriver);
1296 				PM_UNLOCK();
1297 			}
1298 		}
1299 
1300 		// Examine all existing power clients and perform limit check.
1301 
1302 		if (fPowerClients &&
1303 		    (iter = OSCollectionIterator::withCollection(fPowerClients))) {
1304 			const OSSymbol * client;
1305 			while ((client = (const OSSymbol *) iter->getNextObject())) {
1306 				IOPMPowerStateIndex powerState = getPowerStateForClient(client);
1307 				if (powerState >= numberOfStates) {
1308 					updatePowerClient(client, fHighestPowerState);
1309 				}
1310 			}
1311 			iter->release();
1312 		}
1313 
1314 		// Populate IOPMActions for a few special services
1315 		getPMRootDomain()->tagPowerPlaneService(this, &fPMActions, fNumberOfPowerStates - 1);
1316 
1317 		if (inPlane(gIOPowerPlane) && fParentsKnowState) {
1318 			IOPMPowerStateIndex tempDesire;
1319 			fMaxPowerState = fControllingDriver->maxCapabilityForDomainState(fParentsCurrentPowerFlags);
1320 			// initially change into the state we are already in
1321 			tempDesire = fControllingDriver->initialPowerStateForDomainState(fParentsCurrentPowerFlags);
1322 			adjustPowerState(tempDesire);
1323 		}
1324 	} else {
1325 		OUR_PMLog(kPMLogControllingDriverErr2, numberOfStates, 0);
1326 		IODeleteData(powerStates, IOPMPSEntry, numberOfStates);
1327 	}
1328 
1329 	powerDriver->release();
1330 }
1331 
1332 //*********************************************************************************
1333 // [public] registerInterestedDriver
1334 //
1335 // Add the caller to our list of interested drivers and return our current
1336 // power state.  If we don't have a power-controlling driver yet, we will
1337 // call this interested driver again later when we do get a driver and find
1338 // out what the current power state of the device is.
1339 //*********************************************************************************
1340 
1341 IOPMPowerFlags
registerInterestedDriver(IOService * driver)1342 IOService::registerInterestedDriver( IOService * driver )
1343 {
1344 	IOPMRequest *   request;
1345 	bool            signal;
1346 
1347 	if (!driver || !initialized || !fInterestedDrivers) {
1348 		return 0;
1349 	}
1350 
1351 	PM_LOCK();
1352 	signal = (!fInsertInterestSet && !fRemoveInterestSet);
1353 	if (fInsertInterestSet == NULL) {
1354 		fInsertInterestSet = OSSet::withCapacity(4);
1355 	}
1356 	if (fInsertInterestSet) {
1357 		fInsertInterestSet->setObject(driver);
1358 		if (fRemoveInterestSet) {
1359 			fRemoveInterestSet->removeObject(driver);
1360 		}
1361 	}
1362 	PM_UNLOCK();
1363 
1364 	if (signal) {
1365 		request = acquirePMRequest( this, kIOPMRequestTypeInterestChanged );
1366 		if (request) {
1367 			submitPMRequest( request );
1368 		}
1369 	}
1370 
1371 	// This return value cannot be trusted, but return a value
1372 	// for those clients that care.
1373 
1374 	OUR_PMLog(kPMLogInterestedDriver, kIOPMDeviceUsable, 2);
1375 	return kIOPMDeviceUsable;
1376 }
1377 
1378 //*********************************************************************************
1379 // [public] deRegisterInterestedDriver
1380 //*********************************************************************************
1381 
1382 IOReturn
deRegisterInterestedDriver(IOService * driver)1383 IOService::deRegisterInterestedDriver( IOService * driver )
1384 {
1385 	IOPMinformee *      item;
1386 	IOPMRequest *       request;
1387 	bool                signal;
1388 
1389 	if (!driver) {
1390 		return kIOReturnBadArgument;
1391 	}
1392 	if (!initialized || !fInterestedDrivers) {
1393 		return IOPMNotPowerManaged;
1394 	}
1395 
1396 	PM_LOCK();
1397 	if (fInsertInterestSet) {
1398 		fInsertInterestSet->removeObject(driver);
1399 	}
1400 
1401 	item = fInterestedDrivers->findItem(driver);
1402 	if (!item) {
1403 		PM_UNLOCK();
1404 		return kIOReturnNotFound;
1405 	}
1406 
1407 	signal = (!fRemoveInterestSet && !fInsertInterestSet);
1408 	if (fRemoveInterestSet == NULL) {
1409 		fRemoveInterestSet = OSSet::withCapacity(4);
1410 	}
1411 	if (fRemoveInterestSet) {
1412 		fRemoveInterestSet->setObject(driver);
1413 		if (item->active) {
1414 			item->active = false;
1415 			waitForPMDriverCall( driver );
1416 		}
1417 	}
1418 	PM_UNLOCK();
1419 
1420 	if (signal) {
1421 		request = acquirePMRequest( this, kIOPMRequestTypeInterestChanged );
1422 		if (request) {
1423 			submitPMRequest( request );
1424 		}
1425 	}
1426 
1427 	return IOPMNoErr;
1428 }
1429 
1430 //*********************************************************************************
1431 // [private] handleInterestChanged
1432 //
1433 // Handle interest added or removed.
1434 //*********************************************************************************
1435 
1436 void
handleInterestChanged(IOPMRequest * request)1437 IOService::handleInterestChanged( IOPMRequest * request )
1438 {
1439 	IOService *         driver;
1440 	IOPMinformee *      informee;
1441 	IOPMinformeeList *  list = fInterestedDrivers;
1442 
1443 	PM_LOCK();
1444 
1445 	if (fInsertInterestSet) {
1446 		while ((driver = (IOService *) fInsertInterestSet->getAnyObject())) {
1447 			if (list->findItem(driver) == NULL) {
1448 				list->appendNewInformee(driver);
1449 			}
1450 			fInsertInterestSet->removeObject(driver);
1451 		}
1452 		fInsertInterestSet->release();
1453 		fInsertInterestSet = NULL;
1454 	}
1455 
1456 	if (fRemoveInterestSet) {
1457 		while ((driver = (IOService *) fRemoveInterestSet->getAnyObject())) {
1458 			informee = list->findItem(driver);
1459 			if (informee) {
1460 				// Clean-up async interest acknowledgement
1461 				if (fHeadNotePendingAcks && informee->timer) {
1462 					informee->timer = 0;
1463 					fHeadNotePendingAcks--;
1464 				}
1465 				list->removeFromList(driver);
1466 			}
1467 			fRemoveInterestSet->removeObject(driver);
1468 		}
1469 		fRemoveInterestSet->release();
1470 		fRemoveInterestSet = NULL;
1471 	}
1472 
1473 	PM_UNLOCK();
1474 }
1475 
1476 //*********************************************************************************
1477 // [public] acknowledgePowerChange
1478 //
1479 // After we notified one of the interested drivers or a power-domain child
1480 // of an impending change in power, it has called to say it is now
1481 // prepared for the change.  If this object is the last to
1482 // acknowledge this change, we take whatever action we have been waiting
1483 // for.
1484 // That may include acknowledging to our parent.  In this case, we do it
1485 // last of all to insure that this doesn't cause the parent to call us some-
1486 // where else and alter data we are relying on here (like the very existance
1487 // of a "current change note".)
1488 //*********************************************************************************
1489 
1490 IOReturn
acknowledgePowerChange(IOService * whichObject)1491 IOService::acknowledgePowerChange( IOService * whichObject )
1492 {
1493 	IOPMRequest * request;
1494 
1495 	if (!initialized) {
1496 		return IOPMNotYetInitialized;
1497 	}
1498 	if (!whichObject) {
1499 		return kIOReturnBadArgument;
1500 	}
1501 
1502 	request = acquirePMRequest( this, kIOPMRequestTypeAckPowerChange );
1503 	if (!request) {
1504 		return kIOReturnNoMemory;
1505 	}
1506 
1507 	whichObject->retain();
1508 	request->fArg0 = whichObject;
1509 
1510 	submitPMRequest( request );
1511 	return IOPMNoErr;
1512 }
1513 
1514 //*********************************************************************************
1515 // [private] handleAcknowledgePowerChange
1516 //*********************************************************************************
1517 
1518 bool
handleAcknowledgePowerChange(IOPMRequest * request)1519 IOService::handleAcknowledgePowerChange( IOPMRequest * request )
1520 {
1521 	IOPMinformee *      informee;
1522 	IOPMPowerStateIndex childPower = kIOPMUnknown;
1523 	IOService *         theChild;
1524 	IOService *         whichObject;
1525 	bool                all_acked  = false;
1526 
1527 	PM_ASSERT_IN_GATE();
1528 	whichObject = (IOService *) request->fArg0;
1529 	assert(whichObject);
1530 
1531 	// one of our interested drivers?
1532 	informee = fInterestedDrivers->findItem( whichObject );
1533 	if (informee == NULL) {
1534 		if (!isChild(whichObject, gIOPowerPlane)) {
1535 			OUR_PMLog(kPMLogAcknowledgeErr1, 0, 0);
1536 			goto no_err;
1537 		} else {
1538 			OUR_PMLog(kPMLogChildAcknowledge, fHeadNotePendingAcks, 0);
1539 		}
1540 	} else {
1541 		OUR_PMLog(kPMLogDriverAcknowledge, fHeadNotePendingAcks, 0);
1542 	}
1543 
1544 	if (fHeadNotePendingAcks != 0) {
1545 		assert(fPowerStates != NULL);
1546 
1547 		// yes, make sure we're expecting acks
1548 		if (informee != NULL) {
1549 			// it's an interested driver
1550 			// make sure we're expecting this ack
1551 			if (informee->timer != 0) {
1552 				SOCD_TRACE_XNU(PM_INFORM_POWER_CHANGE_ACK,
1553 				    ADDR(informee->whatObject->getMetaClass()),
1554 				    ADDR(this->getMetaClass()),
1555 				    PACK_2X32(VALUE(informee->whatObject->getRegistryEntryID()), VALUE(this->getRegistryEntryID())),
1556 				    PACK_2X32(VALUE(fDriverCallReason), VALUE(0)));
1557 
1558 				if (informee->timer > 0) {
1559 					uint64_t nsec = computeTimeDeltaNS(&informee->startTime);
1560 					if (nsec > gIOPMSetPowerStateLogNS) {
1561 						getPMRootDomain()->pmStatsRecordApplicationResponse(
1562 							gIOPMStatsDriverPSChangeSlow, informee->whatObject->getName(),
1563 							fDriverCallReason, NS_TO_MS(nsec), informee->whatObject->getRegistryEntryID(),
1564 							NULL, fHeadNotePowerState, true);
1565 					}
1566 				}
1567 
1568 				// mark it acked
1569 				informee->timer = 0;
1570 				// that's one fewer to worry about
1571 				fHeadNotePendingAcks--;
1572 			} else {
1573 				// this driver has already acked
1574 				OUR_PMLog(kPMLogAcknowledgeErr2, 0, 0);
1575 			}
1576 		} else {
1577 			// it's a child
1578 			// make sure we're expecting this ack
1579 			if (((IOPowerConnection *)whichObject)->getAwaitingAck()) {
1580 				// that's one fewer to worry about
1581 				fHeadNotePendingAcks--;
1582 				((IOPowerConnection *)whichObject)->setAwaitingAck(false);
1583 				theChild = (IOService *)whichObject->copyChildEntry(gIOPowerPlane);
1584 				if (theChild) {
1585 					childPower = theChild->currentPowerConsumption();
1586 					theChild->release();
1587 				}
1588 				if (childPower == kIOPMUnknown) {
1589 					fHeadNotePowerArrayEntry->staticPower = kIOPMUnknown;
1590 				} else {
1591 					if (fHeadNotePowerArrayEntry->staticPower != kIOPMUnknown) {
1592 						fHeadNotePowerArrayEntry->staticPower += childPower;
1593 					}
1594 				}
1595 			}
1596 		}
1597 
1598 		if (fHeadNotePendingAcks == 0) {
1599 			// yes, stop the timer
1600 			stop_ack_timer();
1601 			// and now we can continue
1602 			all_acked = true;
1603 			getPMRootDomain()->reset_watchdog_timer(this, 0);
1604 		}
1605 	} else {
1606 		OUR_PMLog(kPMLogAcknowledgeErr3, 0, 0); // not expecting anybody to ack
1607 	}
1608 
1609 no_err:
1610 	if (whichObject) {
1611 		whichObject->release();
1612 	}
1613 
1614 	return all_acked;
1615 }
1616 
1617 //*********************************************************************************
1618 // [public] acknowledgeSetPowerState
1619 //
1620 // After we instructed our controlling driver to change power states,
1621 // it has called to say it has finished doing so.
1622 // We continue to process the power state change.
1623 //*********************************************************************************
1624 
1625 IOReturn
acknowledgeSetPowerState(void)1626 IOService::acknowledgeSetPowerState( void )
1627 {
1628 	IOPMRequest * request;
1629 
1630 	if (!initialized) {
1631 		return IOPMNotYetInitialized;
1632 	}
1633 
1634 	request = acquirePMRequest( this, kIOPMRequestTypeAckSetPowerState );
1635 	if (!request) {
1636 		return kIOReturnNoMemory;
1637 	}
1638 
1639 	submitPMRequest( request );
1640 	return kIOReturnSuccess;
1641 }
1642 
1643 //*********************************************************************************
1644 // [private] handleAcknowledgeSetPowerState
1645 //*********************************************************************************
1646 
1647 bool
handleAcknowledgeSetPowerState(IOPMRequest * request __unused)1648 IOService::handleAcknowledgeSetPowerState( IOPMRequest * request __unused)
1649 {
1650 	const OSMetaClass  *controllingDriverMetaClass = NULL;
1651 	uint32_t            controllingDriverRegistryEntryID = 0;
1652 	bool                more = false;
1653 	bool                trace_this_ack = true;
1654 
1655 	if (fDriverTimer == -1) {
1656 		// driver acked while setPowerState() call is in-flight.
1657 		// take this ack, return value from setPowerState() is irrelevant.
1658 		OUR_PMLog(kPMLogDriverAcknowledgeSet,
1659 		    (uintptr_t) this, fDriverTimer);
1660 		fDriverTimer = 0;
1661 	} else if (fDriverTimer > 0) {
1662 		// expected ack, stop the timer
1663 		stop_ack_timer();
1664 
1665 		getPMRootDomain()->reset_watchdog_timer(this, 0);
1666 
1667 		uint64_t nsec = computeTimeDeltaNS(&fDriverCallStartTime);
1668 		if (nsec > gIOPMSetPowerStateLogNS) {
1669 			getPMRootDomain()->pmStatsRecordApplicationResponse(
1670 				gIOPMStatsDriverPSChangeSlow,
1671 				fName, kDriverCallSetPowerState, NS_TO_MS(nsec), getRegistryEntryID(),
1672 				NULL, fHeadNotePowerState, true);
1673 		}
1674 
1675 		OUR_PMLog(kPMLogDriverAcknowledgeSet, (uintptr_t) this, fDriverTimer);
1676 		fDriverTimer = 0;
1677 		more = true;
1678 	} else {
1679 		// unexpected ack
1680 		OUR_PMLog(kPMLogAcknowledgeErr4, (uintptr_t) this, 0);
1681 		trace_this_ack = false;
1682 	}
1683 
1684 	if (trace_this_ack) {
1685 		if (fControllingDriver) {
1686 			controllingDriverMetaClass = fControllingDriver->getMetaClass();
1687 			controllingDriverRegistryEntryID = (uint32_t)fControllingDriver->getRegistryEntryID();
1688 		}
1689 
1690 		SOCD_TRACE_XNU(PM_SET_POWER_STATE_ACK,
1691 		    ADDR(controllingDriverMetaClass),
1692 		    ADDR(this->getMetaClass()),
1693 		    PACK_2X32(VALUE(controllingDriverRegistryEntryID), VALUE(this->getRegistryEntryID())),
1694 		    PACK_2X32(VALUE(0), VALUE(fHeadNotePowerState)));
1695 	}
1696 
1697 	return more;
1698 }
1699 
1700 //*********************************************************************************
1701 // [private] adjustPowerState
1702 //*********************************************************************************
1703 
1704 void
adjustPowerState(IOPMPowerStateIndex clamp)1705 IOService::adjustPowerState( IOPMPowerStateIndex clamp )
1706 {
1707 	PM_ASSERT_IN_GATE();
1708 	computeDesiredState(clamp, false);
1709 	if (fControllingDriver && fParentsKnowState && inPlane(gIOPowerPlane)) {
1710 		IOPMPowerChangeFlags changeFlags = kIOPMSelfInitiated;
1711 
1712 		// Indicate that children desires must be ignored, and do not ask
1713 		// apps for permission to drop power. This is used by root domain
1714 		// for demand sleep.
1715 
1716 		if (getPMRequestType() == kIOPMRequestTypeRequestPowerStateOverride) {
1717 			changeFlags |= (kIOPMIgnoreChildren | kIOPMSkipAskPowerDown);
1718 		}
1719 
1720 		startPowerChange(
1721 			/* flags        */ changeFlags,
1722 			/* power state  */ fDesiredPowerState,
1723 			/* domain flags */ 0,
1724 			/* connection   */ NULL,
1725 			/* parent flags */ 0);
1726 	}
1727 }
1728 
1729 //*********************************************************************************
1730 // [public] synchronizePowerTree
1731 //*********************************************************************************
1732 
1733 IOReturn
synchronizePowerTree(IOOptionBits options,IOService * notifyRoot)1734 IOService::synchronizePowerTree(
1735 	IOOptionBits    options,
1736 	IOService *     notifyRoot )
1737 {
1738 	IOPMRequest *   request_c = NULL;
1739 	IOPMRequest *   request_s;
1740 
1741 	if (this != getPMRootDomain()) {
1742 		return kIOReturnBadArgument;
1743 	}
1744 	if (!initialized) {
1745 		return kIOPMNotYetInitialized;
1746 	}
1747 
1748 	OUR_PMLog(kPMLogCSynchronizePowerTree, options, (notifyRoot != NULL));
1749 
1750 	if (notifyRoot) {
1751 		IOPMRequest * nr;
1752 
1753 		// Cancels don't need to be synchronized.
1754 		nr = acquirePMRequest(notifyRoot, kIOPMRequestTypeChildNotifyDelayCancel);
1755 		if (nr) {
1756 			submitPMRequest(nr);
1757 		}
1758 
1759 		// For display wrangler or any other delay-eligible (dark wake clamped)
1760 		// drivers attached to root domain in the power plane.
1761 		nr = acquirePMRequest(getPMRootDomain(), kIOPMRequestTypeChildNotifyDelayCancel);
1762 		if (nr) {
1763 			submitPMRequest(nr);
1764 		}
1765 	}
1766 
1767 	request_s = acquirePMRequest( this, kIOPMRequestTypeSynchronizePowerTree );
1768 	if (!request_s) {
1769 		goto error_no_memory;
1770 	}
1771 
1772 	if (options & kIOPMSyncCancelPowerDown) {
1773 		request_c = acquirePMRequest( this, kIOPMRequestTypeIdleCancel );
1774 	}
1775 	if (request_c) {
1776 		request_c->attachNextRequest( request_s );
1777 		submitPMRequest(request_c);
1778 	}
1779 
1780 	request_s->fArg0 = (void *)(uintptr_t) options;
1781 	submitPMRequest(request_s);
1782 
1783 	return kIOReturnSuccess;
1784 
1785 error_no_memory:
1786 	if (request_c) {
1787 		releasePMRequest(request_c);
1788 	}
1789 	if (request_s) {
1790 		releasePMRequest(request_s);
1791 	}
1792 	return kIOReturnNoMemory;
1793 }
1794 
1795 //*********************************************************************************
1796 // [private] handleSynchronizePowerTree
1797 //*********************************************************************************
1798 
1799 void
handleSynchronizePowerTree(IOPMRequest * request)1800 IOService::handleSynchronizePowerTree( IOPMRequest * request )
1801 {
1802 	PM_ASSERT_IN_GATE();
1803 	if (fControllingDriver && fParentsKnowState && inPlane(gIOPowerPlane) &&
1804 	    (fCurrentPowerState == fHighestPowerState)) {
1805 		IOPMPowerChangeFlags options = (IOPMPowerChangeFlags)(uintptr_t) request->fArg0;
1806 
1807 		startPowerChange(
1808 			/* flags        */ kIOPMSelfInitiated | kIOPMSynchronize |
1809 			(options & kIOPMSyncNoChildNotify),
1810 			/* power state  */ fCurrentPowerState,
1811 			/* domain flags */ 0,
1812 			/* connection   */ NULL,
1813 			/* parent flags */ 0);
1814 	}
1815 }
1816 
1817 #ifndef __LP64__
1818 //*********************************************************************************
1819 // [deprecated] powerDomainWillChangeTo
1820 //
1821 // Called by the power-hierarchy parent notifying of a new power state
1822 // in the power domain.
1823 // We enqueue a parent power-change to our queue of power changes.
1824 // This may or may not cause us to change power, depending on what
1825 // kind of change is occuring in the domain.
1826 //*********************************************************************************
1827 
1828 IOReturn
powerDomainWillChangeTo(IOPMPowerFlags newPowerFlags,IOPowerConnection * whichParent)1829 IOService::powerDomainWillChangeTo(
1830 	IOPMPowerFlags      newPowerFlags,
1831 	IOPowerConnection * whichParent )
1832 {
1833 	assert(false);
1834 	return kIOReturnUnsupported;
1835 }
1836 #endif /* !__LP64__ */
1837 
1838 //*********************************************************************************
1839 // [private] handlePowerDomainWillChangeTo
1840 //*********************************************************************************
1841 
1842 void
handlePowerDomainWillChangeTo(IOPMRequest * request)1843 IOService::handlePowerDomainWillChangeTo( IOPMRequest * request )
1844 {
1845 	IOPMPowerFlags       parentPowerFlags = (IOPMPowerFlags) request->fArg0;
1846 	IOPowerConnection *  whichParent = (IOPowerConnection *) request->fArg1;
1847 	IOPMPowerChangeFlags parentChangeFlags = (IOPMPowerChangeFlags)(uintptr_t) request->fArg2;
1848 	IOPMPowerChangeFlags myChangeFlags;
1849 	OSIterator *         iter;
1850 	OSObject *           next;
1851 	IOPowerConnection *  connection;
1852 	IOPMPowerStateIndex  maxPowerState;
1853 	IOPMPowerFlags       combinedPowerFlags;
1854 	IOReturn             result = IOPMAckImplied;
1855 
1856 	PM_ASSERT_IN_GATE();
1857 	OUR_PMLog(kPMLogWillChange, parentPowerFlags, 0);
1858 
1859 	if (!inPlane(gIOPowerPlane) || !whichParent || !whichParent->getAwaitingAck()) {
1860 		PM_LOG("%s::%s not in power tree\n", getName(), __FUNCTION__);
1861 		goto exit_no_ack;
1862 	}
1863 
1864 	// Combine parents' output power flags.
1865 
1866 	combinedPowerFlags = 0;
1867 
1868 	iter = getParentIterator(gIOPowerPlane);
1869 	if (iter) {
1870 		while ((next = iter->getNextObject())) {
1871 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
1872 				if (connection == whichParent) {
1873 					combinedPowerFlags |= parentPowerFlags;
1874 				} else {
1875 					combinedPowerFlags |= connection->parentCurrentPowerFlags();
1876 				}
1877 			}
1878 		}
1879 		iter->release();
1880 	}
1881 
1882 	// If our initial change has yet to occur, then defer the power change
1883 	// until after the power domain has completed its power transition.
1884 
1885 	if (fControllingDriver && !fInitialPowerChange) {
1886 		maxPowerState = fControllingDriver->maxCapabilityForDomainState(
1887 			combinedPowerFlags);
1888 
1889 		if (parentChangeFlags & kIOPMDomainPowerDrop) {
1890 			// fMaxPowerState set a limit on self-initiated power changes.
1891 			// Update it before a parent power drop.
1892 			fMaxPowerState = maxPowerState;
1893 		}
1894 
1895 		// Use kIOPMSynchronize below instead of kIOPMRootBroadcastFlags
1896 		// to avoid propagating the root change flags if any service must
1897 		// change power state due to root's will-change notification.
1898 		// Root does not change power state for kIOPMSynchronize.
1899 
1900 		myChangeFlags = kIOPMParentInitiated | kIOPMDomainWillChange |
1901 		    (parentChangeFlags & kIOPMSynchronize);
1902 
1903 		result = startPowerChange(
1904 			/* flags        */ myChangeFlags,
1905 			/* power state  */ maxPowerState,
1906 			/* domain flags */ combinedPowerFlags,
1907 			/* connection   */ whichParent,
1908 			/* parent flags */ parentPowerFlags);
1909 	}
1910 
1911 	// If parent is dropping power, immediately update the parent's
1912 	// capability flags. Any future merging of parent(s) combined
1913 	// power flags should account for this power drop.
1914 
1915 	if (parentChangeFlags & kIOPMDomainPowerDrop) {
1916 		setParentInfo(parentPowerFlags, whichParent, true);
1917 	}
1918 
1919 	// Parent is expecting an ACK from us. If we did not embark on a state
1920 	// transition, i.e. startPowerChange() returned IOPMAckImplied. We are
1921 	// still required to issue an ACK to our parent.
1922 
1923 	if (IOPMAckImplied == result) {
1924 		IOService * parent;
1925 		parent = (IOService *) whichParent->copyParentEntry(gIOPowerPlane);
1926 		assert(parent);
1927 		if (parent) {
1928 			parent->acknowledgePowerChange( whichParent );
1929 			parent->release();
1930 		}
1931 	}
1932 
1933 exit_no_ack:
1934 	// Drop the retain from notifyChild().
1935 	if (whichParent) {
1936 		whichParent->release();
1937 	}
1938 }
1939 
1940 #ifndef __LP64__
1941 //*********************************************************************************
1942 // [deprecated] powerDomainDidChangeTo
1943 //
1944 // Called by the power-hierarchy parent after the power state of the power domain
1945 // has settled at a new level.
1946 // We enqueue a parent power-change to our queue of power changes.
1947 // This may or may not cause us to change power, depending on what
1948 // kind of change is occuring in the domain.
1949 //*********************************************************************************
1950 
1951 IOReturn
powerDomainDidChangeTo(IOPMPowerFlags newPowerFlags,IOPowerConnection * whichParent)1952 IOService::powerDomainDidChangeTo(
1953 	IOPMPowerFlags      newPowerFlags,
1954 	IOPowerConnection * whichParent )
1955 {
1956 	assert(false);
1957 	return kIOReturnUnsupported;
1958 }
1959 #endif /* !__LP64__ */
1960 
1961 //*********************************************************************************
1962 // [private] handlePowerDomainDidChangeTo
1963 //*********************************************************************************
1964 
1965 void
handlePowerDomainDidChangeTo(IOPMRequest * request)1966 IOService::handlePowerDomainDidChangeTo( IOPMRequest * request )
1967 {
1968 	IOPMPowerFlags       parentPowerFlags = (IOPMPowerFlags) request->fArg0;
1969 	IOPowerConnection *  whichParent = (IOPowerConnection *) request->fArg1;
1970 	IOPMPowerChangeFlags parentChangeFlags = (IOPMPowerChangeFlags)(uintptr_t) request->fArg2;
1971 	IOPMPowerChangeFlags myChangeFlags;
1972 	IOPMPowerStateIndex  maxPowerState;
1973 	IOPMPowerStateIndex  initialDesire = kPowerStateZero;
1974 	bool                 computeDesire = false;
1975 	bool                 desireChanged = false;
1976 	bool                 savedParentsKnowState;
1977 	IOReturn             result = IOPMAckImplied;
1978 
1979 	PM_ASSERT_IN_GATE();
1980 	OUR_PMLog(kPMLogDidChange, parentPowerFlags, 0);
1981 
1982 	if (!inPlane(gIOPowerPlane) || !whichParent || !whichParent->getAwaitingAck()) {
1983 		PM_LOG("%s::%s not in power tree\n", getName(), __FUNCTION__);
1984 		goto exit_no_ack;
1985 	}
1986 
1987 	savedParentsKnowState = fParentsKnowState;
1988 
1989 	setParentInfo(parentPowerFlags, whichParent, true);
1990 
1991 	if (fControllingDriver) {
1992 		maxPowerState = fControllingDriver->maxCapabilityForDomainState(
1993 			fParentsCurrentPowerFlags);
1994 
1995 		if ((parentChangeFlags & kIOPMDomainPowerDrop) == 0) {
1996 			// fMaxPowerState set a limit on self-initiated power changes.
1997 			// Update it after a parent power rise.
1998 			fMaxPowerState = maxPowerState;
1999 		}
2000 
2001 		if (fInitialPowerChange) {
2002 			computeDesire = true;
2003 			initialDesire = fControllingDriver->initialPowerStateForDomainState(
2004 				fParentsCurrentPowerFlags);
2005 		} else if (parentChangeFlags & kIOPMRootChangeUp) {
2006 			if (fAdvisoryTickleUsed) {
2007 				// On system wake, re-compute the desired power state since
2008 				// gIOPMAdvisoryTickleEnabled will change for a full wake,
2009 				// which is an input to computeDesiredState(). This is not
2010 				// necessary for a dark wake because powerChangeDone() will
2011 				// handle the dark to full wake case, but it does no harm.
2012 
2013 				desireChanged = true;
2014 			}
2015 
2016 			if (fResetPowerStateOnWake) {
2017 				// Query the driver for the desired power state on system wake.
2018 				// Default implementation returns the lowest power state.
2019 
2020 				IOPMPowerStateIndex wakePowerState =
2021 				    fControllingDriver->initialPowerStateForDomainState(
2022 					kIOPMRootDomainState | kIOPMPowerOn );
2023 
2024 				// fDesiredPowerState was adjusted before going to sleep
2025 				// with fDeviceDesire at min.
2026 
2027 				if (StateOrder(wakePowerState) > StateOrder(fDesiredPowerState)) {
2028 					// Must schedule a power adjustment if we changed the
2029 					// device desire. That will update the desired domain
2030 					// power on the parent power connection and ping the
2031 					// power parent if necessary.
2032 
2033 					updatePowerClient(gIOPMPowerClientDevice, wakePowerState);
2034 					desireChanged = true;
2035 				}
2036 			}
2037 		}
2038 
2039 		if (computeDesire || desireChanged) {
2040 			computeDesiredState(initialDesire, false);
2041 		}
2042 
2043 		// Absorb and propagate parent's broadcast flags
2044 		myChangeFlags = kIOPMParentInitiated | kIOPMDomainDidChange |
2045 		    (parentChangeFlags & kIOPMRootBroadcastFlags);
2046 
2047 		if (kIOPMAOTPower & fPowerStates[maxPowerState].inputPowerFlags) {
2048 			IOLog("aotPS %s0x%qx[%ld]\n", getName(), getRegistryEntryID(), maxPowerState);
2049 		}
2050 
2051 		result = startPowerChange(
2052 			/* flags        */ myChangeFlags,
2053 			/* power state  */ maxPowerState,
2054 			/* domain flags */ fParentsCurrentPowerFlags,
2055 			/* connection   */ whichParent,
2056 			/* parent flags */ 0);
2057 	}
2058 
2059 	// Parent is expecting an ACK from us. If we did not embark on a state
2060 	// transition, i.e. startPowerChange() returned IOPMAckImplied. We are
2061 	// still required to issue an ACK to our parent.
2062 
2063 	if (IOPMAckImplied == result) {
2064 		IOService * parent;
2065 		parent = (IOService *) whichParent->copyParentEntry(gIOPowerPlane);
2066 		assert(parent);
2067 		if (parent) {
2068 			parent->acknowledgePowerChange( whichParent );
2069 			parent->release();
2070 		}
2071 	}
2072 
2073 	// If the parent registers its power driver late, then this is the
2074 	// first opportunity to tell our parent about our desire. Or if the
2075 	// child's desire changed during a parent change notify.
2076 
2077 	if (fControllingDriver &&
2078 	    ((!savedParentsKnowState && fParentsKnowState) || desireChanged)) {
2079 		PM_LOG1("%s::powerDomainDidChangeTo parentsKnowState %d\n",
2080 		    getName(), fParentsKnowState);
2081 		requestDomainPower( fDesiredPowerState );
2082 	}
2083 
2084 exit_no_ack:
2085 	// Drop the retain from notifyChild().
2086 	if (whichParent) {
2087 		whichParent->release();
2088 	}
2089 }
2090 
2091 //*********************************************************************************
2092 // [private] setParentInfo
2093 //
2094 // Set our connection data for one specific parent, and then combine all the parent
2095 // data together.
2096 //*********************************************************************************
2097 
2098 void
setParentInfo(IOPMPowerFlags newPowerFlags,IOPowerConnection * whichParent,bool knowsState)2099 IOService::setParentInfo(
2100 	IOPMPowerFlags      newPowerFlags,
2101 	IOPowerConnection * whichParent,
2102 	bool                knowsState )
2103 {
2104 	OSIterator *        iter;
2105 	OSObject *          next;
2106 	IOPowerConnection * conn;
2107 
2108 	PM_ASSERT_IN_GATE();
2109 
2110 	// set our connection data
2111 	whichParent->setParentCurrentPowerFlags(newPowerFlags);
2112 	whichParent->setParentKnowsState(knowsState);
2113 
2114 	// recompute our parent info
2115 	fParentsCurrentPowerFlags = 0;
2116 	fParentsKnowState = true;
2117 
2118 	iter = getParentIterator(gIOPowerPlane);
2119 	if (iter) {
2120 		while ((next = iter->getNextObject())) {
2121 			if ((conn = OSDynamicCast(IOPowerConnection, next))) {
2122 				fParentsKnowState &= conn->parentKnowsState();
2123 				fParentsCurrentPowerFlags |= conn->parentCurrentPowerFlags();
2124 			}
2125 		}
2126 		iter->release();
2127 	}
2128 }
2129 
2130 //******************************************************************************
2131 // [private] trackSystemSleepPreventers
2132 //******************************************************************************
2133 
2134 void
trackSystemSleepPreventers(IOPMPowerStateIndex oldPowerState,IOPMPowerStateIndex newPowerState,IOPMPowerChangeFlags changeFlags __unused)2135 IOService::trackSystemSleepPreventers(
2136 	IOPMPowerStateIndex     oldPowerState,
2137 	IOPMPowerStateIndex     newPowerState,
2138 	IOPMPowerChangeFlags    changeFlags __unused )
2139 {
2140 	IOPMPowerFlags  oldCapability, newCapability;
2141 
2142 	oldCapability = fPowerStates[oldPowerState].capabilityFlags &
2143 	    (kIOPMPreventIdleSleep | kIOPMPreventSystemSleep);
2144 	newCapability = fPowerStates[newPowerState].capabilityFlags &
2145 	    (kIOPMPreventIdleSleep | kIOPMPreventSystemSleep);
2146 
2147 	if (fHeadNoteChangeFlags & kIOPMInitialPowerChange) {
2148 		oldCapability = 0;
2149 	}
2150 	if (oldCapability == newCapability) {
2151 		return;
2152 	}
2153 
2154 	if ((oldCapability ^ newCapability) & kIOPMPreventIdleSleep) {
2155 		bool enablePrevention  = ((oldCapability & kIOPMPreventIdleSleep) == 0);
2156 		bool idleCancelAllowed = getPMRootDomain()->updatePreventIdleSleepList(
2157 			this, enablePrevention);
2158 #if SUPPORT_IDLE_CANCEL
2159 		if (idleCancelAllowed && enablePrevention) {
2160 			IOPMRequest *   cancelRequest;
2161 
2162 			cancelRequest = acquirePMRequest( getPMRootDomain(), kIOPMRequestTypeIdleCancel );
2163 			if (cancelRequest) {
2164 				submitPMRequest( cancelRequest );
2165 			}
2166 		}
2167 #endif
2168 	}
2169 
2170 	if ((oldCapability ^ newCapability) & kIOPMPreventSystemSleep) {
2171 		getPMRootDomain()->updatePreventSystemSleepList(this,
2172 		    ((oldCapability & kIOPMPreventSystemSleep) == 0));
2173 	}
2174 }
2175 
2176 //*********************************************************************************
2177 // [public] requestPowerDomainState
2178 //
2179 // Called on a power parent when a child's power requirement changes.
2180 //*********************************************************************************
2181 
2182 IOReturn
requestPowerDomainState(IOPMPowerFlags childRequestPowerFlags,IOPowerConnection * childConnection,unsigned long specification)2183 IOService::requestPowerDomainState(
2184 	IOPMPowerFlags      childRequestPowerFlags,
2185 	IOPowerConnection * childConnection,
2186 	unsigned long       specification )
2187 {
2188 	IOPMPowerStateIndex order, powerState;
2189 	IOPMPowerFlags      outputPowerFlags;
2190 	IOService *         child;
2191 	IOPMRequest *       subRequest;
2192 	bool                adjustPower = false;
2193 
2194 	if (!initialized) {
2195 		return IOPMNotYetInitialized;
2196 	}
2197 
2198 	if (gIOPMWorkLoop->onThread() == false) {
2199 		PM_LOG("%s::requestPowerDomainState\n", getName());
2200 		return kIOReturnSuccess;
2201 	}
2202 
2203 	OUR_PMLog(kPMLogRequestDomain, childRequestPowerFlags, specification);
2204 
2205 	if (!isChild(childConnection, gIOPowerPlane)) {
2206 		return kIOReturnNotAttached;
2207 	}
2208 
2209 	if (!fControllingDriver || !fNumberOfPowerStates) {
2210 		return kIOReturnNotReady;
2211 	}
2212 
2213 	child = (IOService *) childConnection->getChildEntry(gIOPowerPlane);
2214 	assert(child);
2215 
2216 	// Remove flags from child request which we can't possibly supply
2217 	childRequestPowerFlags &= fMergedOutputPowerFlags;
2218 
2219 	// Merge in the power flags contributed by this power parent
2220 	// at its current or impending power state.
2221 
2222 	outputPowerFlags = fPowerStates[fCurrentPowerState].outputPowerFlags;
2223 	if (fMachineState != kIOPM_Finished) {
2224 		if (IS_POWER_DROP && !IS_ROOT_DOMAIN) {
2225 			// Use the lower power state when dropping power.
2226 			// Must be careful since a power drop can be cancelled
2227 			// from the following states:
2228 			// - kIOPM_OurChangeTellClientsPowerDown
2229 			// - kIOPM_OurChangeTellPriorityClientsPowerDown
2230 			//
2231 			// The child must not wait for this parent to raise power
2232 			// if the power drop was cancelled. The solution is to cancel
2233 			// the power drop if possible, then schedule an adjustment to
2234 			// re-evaluate the parent's power state.
2235 			//
2236 			// Root domain is excluded to avoid idle sleep issues. And allow
2237 			// root domain children to pop up when system is going to sleep.
2238 
2239 			if ((fMachineState == kIOPM_OurChangeTellClientsPowerDown) ||
2240 			    (fMachineState == kIOPM_OurChangeTellPriorityClientsPowerDown)) {
2241 				fDoNotPowerDown = true; // cancel power drop
2242 				adjustPower     = true;// schedule an adjustment
2243 				PM_LOG1("%s: power drop cancelled in state %u by %s\n",
2244 				    getName(), fMachineState, child->getName());
2245 			} else {
2246 				// Beyond cancellation point, report the impending state.
2247 				outputPowerFlags =
2248 				    fPowerStates[fHeadNotePowerState].outputPowerFlags;
2249 			}
2250 		} else if (IS_POWER_RISE) {
2251 			// When raising power, must report the output power flags from
2252 			// child's perspective. A child power request may arrive while
2253 			// parent is transitioning upwards. If a request arrives after
2254 			// setParentInfo() has already recorded the output power flags
2255 			// for the next power state, then using the power supplied by
2256 			// fCurrentPowerState is incorrect, and might cause the child
2257 			// to wait when it should not.
2258 
2259 			outputPowerFlags = childConnection->parentCurrentPowerFlags();
2260 		}
2261 	}
2262 	child->fHeadNoteDomainTargetFlags |= outputPowerFlags;
2263 
2264 	// Map child's requested power flags to one of our power state.
2265 
2266 	for (order = 0; order < fNumberOfPowerStates; order++) {
2267 		powerState = fPowerStates[order].stateOrderToIndex;
2268 		if ((fPowerStates[powerState].outputPowerFlags & childRequestPowerFlags)
2269 		    == childRequestPowerFlags) {
2270 			break;
2271 		}
2272 	}
2273 	if (order >= fNumberOfPowerStates) {
2274 		powerState = kPowerStateZero;
2275 	}
2276 
2277 	// Conditions that warrants a power adjustment on this parent.
2278 	// Adjust power will also propagate any changes to the child's
2279 	// prevent idle/sleep flags towards the root domain.
2280 
2281 	if (!childConnection->childHasRequestedPower() ||
2282 	    (powerState != childConnection->getDesiredDomainState())) {
2283 		adjustPower = true;
2284 	}
2285 
2286 #if ENABLE_DEBUG_LOGS
2287 	if (adjustPower) {
2288 		PM_LOG("requestPowerDomainState[%s]: %s, init %d, %u->%u\n",
2289 		    getName(), child->getName(),
2290 		    !childConnection->childHasRequestedPower(),
2291 		    (uint32_t) childConnection->getDesiredDomainState(),
2292 		    (uint32_t) powerState);
2293 	}
2294 #endif
2295 
2296 	// Record the child's desires on the connection.
2297 	childConnection->setChildHasRequestedPower();
2298 	childConnection->setDesiredDomainState( powerState );
2299 
2300 	// Schedule a request to re-evaluate all children desires and
2301 	// adjust power state. Submit a request if one wasn't pending,
2302 	// or if the current request is part of a call tree.
2303 
2304 	if (adjustPower && !fDeviceOverrideEnabled &&
2305 	    (!fAdjustPowerScheduled || gIOPMRequest->getRootRequest())) {
2306 		subRequest = acquirePMRequest(
2307 			this, kIOPMRequestTypeAdjustPowerState, gIOPMRequest );
2308 		if (subRequest) {
2309 			submitPMRequest( subRequest );
2310 			fAdjustPowerScheduled = true;
2311 		}
2312 	}
2313 
2314 	return kIOReturnSuccess;
2315 }
2316 
2317 //*********************************************************************************
2318 // [public] temporaryPowerClampOn
2319 //
2320 // A power domain wants to be clamped to max power until it has children which
2321 // will then determine the power domain state.
2322 //
2323 // We enter the highest state until addPowerChild is called.
2324 //*********************************************************************************
2325 
2326 IOReturn
temporaryPowerClampOn(void)2327 IOService::temporaryPowerClampOn( void )
2328 {
2329 	return requestPowerState( gIOPMPowerClientChildProxy, kIOPMPowerStateMax );
2330 }
2331 
2332 //*********************************************************************************
2333 // [public] makeUsable
2334 //
2335 // Some client of our device is asking that we become usable.  Although
2336 // this has not come from a subclassed device object, treat it exactly
2337 // as if it had.  In this way, subsequent requests for lower power from
2338 // a subclassed device object will pre-empt this request.
2339 //
2340 // We treat this as a subclass object request to switch to the
2341 // highest power state.
2342 //*********************************************************************************
2343 
2344 IOReturn
makeUsable(void)2345 IOService::makeUsable( void )
2346 {
2347 	OUR_PMLog(kPMLogMakeUsable, 0, 0);
2348 	return requestPowerState( gIOPMPowerClientDevice, kIOPMPowerStateMax );
2349 }
2350 
2351 //*********************************************************************************
2352 // [public] currentCapability
2353 //*********************************************************************************
2354 
2355 IOPMPowerFlags
currentCapability(void)2356 IOService::currentCapability( void )
2357 {
2358 	if (!initialized) {
2359 		return IOPMNotPowerManaged;
2360 	}
2361 
2362 	return fCurrentCapabilityFlags;
2363 }
2364 
2365 //*********************************************************************************
2366 // [public] changePowerStateTo
2367 //
2368 // Called by our power-controlling driver to change power state. The new desired
2369 // power state is computed and compared against the current power state. If those
2370 // power states differ, then a power state change is initiated.
2371 //*********************************************************************************
2372 
2373 IOReturn
changePowerStateTo(unsigned long ordinal)2374 IOService::changePowerStateTo( unsigned long ordinal )
2375 {
2376 	OUR_PMLog(kPMLogChangeStateTo, ordinal, 0);
2377 	return requestPowerState( gIOPMPowerClientDriver, ordinal );
2378 }
2379 
2380 //*********************************************************************************
2381 // [protected] changePowerStateToPriv
2382 //
2383 // Called by our driver subclass to change power state. The new desired power
2384 // state is computed and compared against the current power state. If those
2385 // power states differ, then a power state change is initiated.
2386 //*********************************************************************************
2387 
2388 IOReturn
changePowerStateToPriv(unsigned long ordinal)2389 IOService::changePowerStateToPriv( unsigned long ordinal )
2390 {
2391 	OUR_PMLog(kPMLogChangeStateToPriv, ordinal, 0);
2392 	return requestPowerState( gIOPMPowerClientDevice, ordinal );
2393 }
2394 
2395 //*********************************************************************************
2396 // [public] changePowerStateWithOverrideTo
2397 //
2398 // Called by our driver subclass to change power state. The new desired power
2399 // state is computed and compared against the current power state. If those
2400 // power states differ, then a power state change is initiated.
2401 // Override enforced - Children and Driver desires are ignored.
2402 //*********************************************************************************
2403 
2404 IOReturn
changePowerStateWithOverrideTo(IOPMPowerStateIndex ordinal,IOPMRequestTag tag)2405 IOService::changePowerStateWithOverrideTo( IOPMPowerStateIndex ordinal,
2406     IOPMRequestTag tag )
2407 {
2408 	IOPMRequest * request;
2409 
2410 	if (!initialized) {
2411 		return kIOPMNotYetInitialized;
2412 	}
2413 
2414 	OUR_PMLog(kPMLogChangeStateToPriv, ordinal, 0);
2415 
2416 	request = acquirePMRequest( this, kIOPMRequestTypeRequestPowerStateOverride );
2417 	if (!request) {
2418 		return kIOReturnNoMemory;
2419 	}
2420 
2421 	gIOPMPowerClientDevice->retain();
2422 	request->fTag  = tag;
2423 	request->fArg0 = (void *) ordinal;
2424 	request->fArg1 = (void *) gIOPMPowerClientDevice;
2425 	request->fArg2 = NULL;
2426 #if NOT_READY
2427 	if (action) {
2428 		request->installCompletionAction( action, target, param );
2429 	}
2430 #endif
2431 
2432 	// Prevent needless downwards power transitions by clamping power
2433 	// until the scheduled request is executed.
2434 	//
2435 	// TODO: review fOverrideMaxPowerState
2436 
2437 	if (gIOPMWorkLoop->inGate() && (ordinal < fNumberOfPowerStates)) {
2438 		fTempClampPowerState = StateMax(fTempClampPowerState, ordinal);
2439 		fTempClampCount++;
2440 		request->fArg2 = (void *)(uintptr_t) true;
2441 
2442 		// Place a power state ceiling to prevent any transition to a
2443 		// power state higher than fOverrideMaxPowerState.
2444 		fOverrideMaxPowerState = ordinal;
2445 	}
2446 
2447 	submitPMRequest( request );
2448 	return IOPMNoErr;
2449 }
2450 
2451 //*********************************************************************************
2452 // Tagged form of changePowerStateTo()
2453 //*********************************************************************************
2454 
2455 IOReturn
changePowerStateWithTagTo(IOPMPowerStateIndex ordinal,IOPMRequestTag tag)2456 IOService::changePowerStateWithTagTo( IOPMPowerStateIndex ordinal, IOPMRequestTag tag )
2457 {
2458 	OUR_PMLog(kPMLogChangeStateTo, ordinal, tag);
2459 	return requestPowerState(gIOPMPowerClientDriver, ordinal, tag);
2460 }
2461 
2462 //*********************************************************************************
2463 // Tagged form of changePowerStateToPriv()
2464 //*********************************************************************************
2465 
2466 IOReturn
changePowerStateWithTagToPriv(unsigned long ordinal,IOPMRequestTag tag)2467 IOService::changePowerStateWithTagToPriv( unsigned long ordinal, IOPMRequestTag tag )
2468 {
2469 	OUR_PMLog(kPMLogChangeStateToPriv, ordinal, tag);
2470 	return requestPowerState(gIOPMPowerClientDevice, ordinal, tag);
2471 }
2472 
2473 //*********************************************************************************
2474 // [public] changePowerStateForRootDomain
2475 //
2476 // Adjust the root domain's power desire on the target
2477 //*********************************************************************************
2478 
2479 IOReturn
changePowerStateForRootDomain(IOPMPowerStateIndex ordinal)2480 IOService::changePowerStateForRootDomain( IOPMPowerStateIndex ordinal )
2481 {
2482 	OUR_PMLog(kPMLogChangeStateForRootDomain, ordinal, 0);
2483 	return requestPowerState( gIOPMPowerClientRootDomain, ordinal );
2484 }
2485 
2486 //*********************************************************************************
2487 // [public for PMRD] quiescePowerTree
2488 //
2489 // For root domain to issue a request to quiesce the power tree.
2490 // Supplied callback invoked upon completion.
2491 //*********************************************************************************
2492 
2493 IOReturn
quiescePowerTree(void * target,IOPMCompletionAction action,void * param)2494 IOService::quiescePowerTree(
2495 	void * target, IOPMCompletionAction action, void * param )
2496 {
2497 	IOPMRequest * request;
2498 
2499 	if (!initialized) {
2500 		return kIOPMNotYetInitialized;
2501 	}
2502 	if (!target || !action) {
2503 		return kIOReturnBadArgument;
2504 	}
2505 
2506 	OUR_PMLog(kPMLogQuiescePowerTree, 0, 0);
2507 
2508 	// Target the root node instead of root domain. This is to avoid blocking
2509 	// the quiesce request behind an existing root domain request in the work
2510 	// queue. Root parent and root domain requests in the work queue must not
2511 	// block the completion of the quiesce request.
2512 
2513 	request = acquirePMRequest(gIOPMRootNode, kIOPMRequestTypeQuiescePowerTree);
2514 	if (!request) {
2515 		return kIOReturnNoMemory;
2516 	}
2517 
2518 	request->installCompletionAction(target, action, param);
2519 
2520 	// Submit through the normal request flow. This will make sure any request
2521 	// already in the request queue will get pushed over to the work queue for
2522 	// execution. Any request submitted after this request may not be serviced.
2523 
2524 	submitPMRequest( request );
2525 	return kIOReturnSuccess;
2526 }
2527 
2528 //*********************************************************************************
2529 // [private] requestPowerState
2530 //*********************************************************************************
2531 
2532 IOReturn
requestPowerState(const OSSymbol * client,IOPMPowerStateIndex state,IOPMRequestTag tag)2533 IOService::requestPowerState(
2534 	const OSSymbol *      client,
2535 	IOPMPowerStateIndex   state,
2536 	IOPMRequestTag        tag )
2537 {
2538 	IOPMRequest * request;
2539 
2540 	if (!client || (state > UINT_MAX)) {
2541 		return kIOReturnBadArgument;
2542 	}
2543 	if (!initialized) {
2544 		return kIOPMNotYetInitialized;
2545 	}
2546 
2547 	request = acquirePMRequest( this, kIOPMRequestTypeRequestPowerState );
2548 	if (!request) {
2549 		return kIOReturnNoMemory;
2550 	}
2551 
2552 	client->retain();
2553 	request->fTag  = tag;
2554 	request->fArg0 = (void *)(uintptr_t) state;
2555 	request->fArg1 = (void *)            client;
2556 	request->fArg2 = NULL;
2557 #if NOT_READY
2558 	if (action) {
2559 		request->installCompletionAction( action, target, param );
2560 	}
2561 #endif
2562 
2563 	// Prevent needless downwards power transitions by clamping power
2564 	// until the scheduled request is executed.
2565 
2566 	if (gIOPMWorkLoop->inGate() && (state < fNumberOfPowerStates)) {
2567 		fTempClampPowerState = StateMax(fTempClampPowerState, state);
2568 		fTempClampCount++;
2569 		request->fArg2 = (void *)(uintptr_t) true;
2570 	}
2571 
2572 	submitPMRequest( request );
2573 	return IOPMNoErr;
2574 }
2575 
2576 //*********************************************************************************
2577 // [private] handleRequestPowerState
2578 //*********************************************************************************
2579 
2580 void
handleRequestPowerState(IOPMRequest * request)2581 IOService::handleRequestPowerState( IOPMRequest * request )
2582 {
2583 	const OSSymbol * client   = (const OSSymbol *)    request->fArg1;
2584 	IOPMPowerStateIndex state = (IOPMPowerStateIndex) request->fArg0;
2585 
2586 	PM_ASSERT_IN_GATE();
2587 	if (request->fArg2) {
2588 		assert(fTempClampCount != 0);
2589 		if (fTempClampCount) {
2590 			fTempClampCount--;
2591 		}
2592 		if (!fTempClampCount) {
2593 			fTempClampPowerState = kPowerStateZero;
2594 		}
2595 	}
2596 
2597 	if (fNumberOfPowerStates && (state >= fNumberOfPowerStates)) {
2598 		state = fHighestPowerState;
2599 	}
2600 
2601 	// The power suppression due to changePowerStateWithOverrideTo() expires
2602 	// upon the next "device" power request - changePowerStateToPriv().
2603 
2604 	if ((getPMRequestType() != kIOPMRequestTypeRequestPowerStateOverride) &&
2605 	    (client == gIOPMPowerClientDevice)) {
2606 		fOverrideMaxPowerState = kIOPMPowerStateMax;
2607 	}
2608 
2609 	if ((state == kPowerStateZero) &&
2610 	    (client != gIOPMPowerClientDevice) &&
2611 	    (client != gIOPMPowerClientDriver) &&
2612 	    (client != gIOPMPowerClientChildProxy)) {
2613 		removePowerClient(client);
2614 	} else {
2615 		updatePowerClient(client, state);
2616 	}
2617 
2618 	adjustPowerState();
2619 	client->release();
2620 }
2621 
2622 //*********************************************************************************
2623 // [private] Helper functions to update/remove power clients.
2624 //*********************************************************************************
2625 
2626 void
updatePowerClient(const OSSymbol * client,IOPMPowerStateIndex powerState)2627 IOService::updatePowerClient( const OSSymbol * client, IOPMPowerStateIndex powerState )
2628 {
2629 	IOPMPowerStateIndex oldPowerState = kPowerStateZero;
2630 
2631 	if (powerState > UINT_MAX) {
2632 		assert(false);
2633 		return;
2634 	}
2635 
2636 	if (!fPowerClients) {
2637 		fPowerClients = OSDictionary::withCapacity(4);
2638 	}
2639 	if (fPowerClients && client) {
2640 		OSNumber * num = (OSNumber *) fPowerClients->getObject(client);
2641 		if (num) {
2642 			oldPowerState = num->unsigned32BitValue();
2643 			num->setValue(powerState);
2644 		} else {
2645 			num = OSNumber::withNumber(powerState, 32);
2646 			if (num) {
2647 				fPowerClients->setObject(client, num);
2648 				num->release();
2649 			}
2650 		}
2651 
2652 		PM_ACTION_CLIENT(actionUpdatePowerClient, client, oldPowerState, powerState);
2653 	}
2654 }
2655 
2656 void
removePowerClient(const OSSymbol * client)2657 IOService::removePowerClient( const OSSymbol * client )
2658 {
2659 	if (fPowerClients && client) {
2660 		fPowerClients->removeObject(client);
2661 	}
2662 }
2663 
2664 IOPMPowerStateIndex
getPowerStateForClient(const OSSymbol * client)2665 IOService::getPowerStateForClient( const OSSymbol * client )
2666 {
2667 	IOPMPowerStateIndex powerState = kPowerStateZero;
2668 
2669 	if (fPowerClients && client) {
2670 		OSNumber * num = (OSNumber *) fPowerClients->getObject(client);
2671 		if (num) {
2672 			powerState = num->unsigned32BitValue();
2673 		}
2674 	}
2675 	return powerState;
2676 }
2677 
2678 //*********************************************************************************
2679 // [protected] powerOverrideOnPriv
2680 //*********************************************************************************
2681 
2682 IOReturn
powerOverrideOnPriv(void)2683 IOService::powerOverrideOnPriv( void )
2684 {
2685 	IOPMRequest * request;
2686 
2687 	if (!initialized) {
2688 		return IOPMNotYetInitialized;
2689 	}
2690 
2691 	if (gIOPMWorkLoop->inGate()) {
2692 		fDeviceOverrideEnabled = true;
2693 		return IOPMNoErr;
2694 	}
2695 
2696 	request = acquirePMRequest( this, kIOPMRequestTypePowerOverrideOnPriv );
2697 	if (!request) {
2698 		return kIOReturnNoMemory;
2699 	}
2700 
2701 	submitPMRequest( request );
2702 	return IOPMNoErr;
2703 }
2704 
2705 //*********************************************************************************
2706 // [protected] powerOverrideOffPriv
2707 //*********************************************************************************
2708 
2709 IOReturn
powerOverrideOffPriv(void)2710 IOService::powerOverrideOffPriv( void )
2711 {
2712 	IOPMRequest * request;
2713 
2714 	if (!initialized) {
2715 		return IOPMNotYetInitialized;
2716 	}
2717 
2718 	if (gIOPMWorkLoop->inGate()) {
2719 		fDeviceOverrideEnabled = false;
2720 		return IOPMNoErr;
2721 	}
2722 
2723 	request = acquirePMRequest( this, kIOPMRequestTypePowerOverrideOffPriv );
2724 	if (!request) {
2725 		return kIOReturnNoMemory;
2726 	}
2727 
2728 	submitPMRequest( request );
2729 	return IOPMNoErr;
2730 }
2731 
2732 //*********************************************************************************
2733 // [private] handlePowerOverrideChanged
2734 //*********************************************************************************
2735 
2736 void
handlePowerOverrideChanged(IOPMRequest * request)2737 IOService::handlePowerOverrideChanged( IOPMRequest * request )
2738 {
2739 	PM_ASSERT_IN_GATE();
2740 	if (request->getType() == kIOPMRequestTypePowerOverrideOnPriv) {
2741 		OUR_PMLog(kPMLogOverrideOn, 0, 0);
2742 		fDeviceOverrideEnabled = true;
2743 	} else {
2744 		OUR_PMLog(kPMLogOverrideOff, 0, 0);
2745 		fDeviceOverrideEnabled = false;
2746 	}
2747 
2748 	adjustPowerState();
2749 }
2750 
2751 //*********************************************************************************
2752 // [private] computeDesiredState
2753 //*********************************************************************************
2754 
2755 void
computeDesiredState(unsigned long localClamp,bool computeOnly)2756 IOService::computeDesiredState( unsigned long localClamp, bool computeOnly )
2757 {
2758 	OSIterator *        iter;
2759 	OSObject *          next;
2760 	IOPowerConnection * connection;
2761 	IOPMPowerStateIndex desiredState  = kPowerStateZero;
2762 	IOPMPowerStateIndex newPowerState = kPowerStateZero;
2763 	bool                hasChildren   = false;
2764 
2765 	// Desired power state is always 0 without a controlling driver.
2766 
2767 	if (!fNumberOfPowerStates) {
2768 		fDesiredPowerState = kPowerStateZero;
2769 		return;
2770 	}
2771 
2772 	// Examine the children's desired power state.
2773 
2774 	iter = getChildIterator(gIOPowerPlane);
2775 	if (iter) {
2776 		while ((next = iter->getNextObject())) {
2777 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
2778 				if (connection->getReadyFlag() == false) {
2779 					PM_LOG3("[%s] %s: connection not ready\n",
2780 					    getName(), __FUNCTION__);
2781 					continue;
2782 				}
2783 				if (connection->childHasRequestedPower()) {
2784 					hasChildren = true;
2785 				}
2786 				desiredState = StateMax(connection->getDesiredDomainState(), desiredState);
2787 			}
2788 		}
2789 		iter->release();
2790 	}
2791 	if (hasChildren) {
2792 		updatePowerClient(gIOPMPowerClientChildren, desiredState);
2793 	} else {
2794 		removePowerClient(gIOPMPowerClientChildren);
2795 	}
2796 
2797 	// Iterate through all power clients to determine the min power state.
2798 
2799 	iter = OSCollectionIterator::withCollection(fPowerClients);
2800 	if (iter) {
2801 		const OSSymbol * client;
2802 		while ((client = (const OSSymbol *) iter->getNextObject())) {
2803 			// Ignore child and driver when override is in effect.
2804 			if ((fDeviceOverrideEnabled ||
2805 			    (getPMRequestType() == kIOPMRequestTypeRequestPowerStateOverride)) &&
2806 			    ((client == gIOPMPowerClientChildren) ||
2807 			    (client == gIOPMPowerClientDriver))) {
2808 				continue;
2809 			}
2810 
2811 			// Ignore child proxy when children are present.
2812 			if (hasChildren && (client == gIOPMPowerClientChildProxy)) {
2813 				continue;
2814 			}
2815 
2816 			// Advisory tickles are irrelevant unless system is in full wake
2817 			if (client == gIOPMPowerClientAdvisoryTickle &&
2818 			    !gIOPMAdvisoryTickleEnabled) {
2819 				continue;
2820 			}
2821 
2822 			desiredState = getPowerStateForClient(client);
2823 			assert(desiredState < fNumberOfPowerStates);
2824 			PM_LOG1("  %u %s\n",
2825 			    (uint32_t) desiredState, client->getCStringNoCopy());
2826 
2827 			newPowerState = StateMax(newPowerState, desiredState);
2828 
2829 			if (client == gIOPMPowerClientDevice) {
2830 				fDeviceDesire = desiredState;
2831 			}
2832 		}
2833 		iter->release();
2834 	}
2835 
2836 	// Factor in the temporary power desires.
2837 
2838 	newPowerState = StateMax(newPowerState, localClamp);
2839 	newPowerState = StateMax(newPowerState, fTempClampPowerState);
2840 
2841 	// Limit check against max power override.
2842 
2843 	newPowerState = StateMin(newPowerState, fOverrideMaxPowerState);
2844 
2845 	// Limit check against number of power states.
2846 
2847 	if (newPowerState >= fNumberOfPowerStates) {
2848 		newPowerState = fHighestPowerState;
2849 	}
2850 
2851 	if (getPMRootDomain()->isAOTMode()) {
2852 		if ((kIOPMPreventIdleSleep & fPowerStates[newPowerState].capabilityFlags)
2853 		    && !(kIOPMPreventIdleSleep & fPowerStates[fDesiredPowerState].capabilityFlags)) {
2854 			getPMRootDomain()->claimSystemWakeEvent(this, kIOPMWakeEventAOTExit, getName(), NULL);
2855 		}
2856 	}
2857 
2858 	fDesiredPowerState = newPowerState;
2859 
2860 	PM_LOG1("  temp %u, clamp %u, current %u, new %u\n",
2861 	    (uint32_t) localClamp, (uint32_t) fTempClampPowerState,
2862 	    (uint32_t) fCurrentPowerState, (uint32_t) newPowerState);
2863 
2864 	if (!computeOnly) {
2865 		// Restart idle timer if possible when device desire has increased.
2866 		// Or if an advisory desire exists.
2867 
2868 		if (fIdleTimerPeriod && fIdleTimerStopped) {
2869 			restartIdleTimer();
2870 		}
2871 
2872 		// Invalidate cached tickle power state when desires change, and not
2873 		// due to a tickle request. In case the driver has requested a lower
2874 		// power state, but the tickle is caching a higher power state which
2875 		// will drop future tickles until the cached value is lowered or in-
2876 		// validated. The invalidation must occur before the power transition
2877 		// to avoid dropping a necessary tickle.
2878 
2879 		if ((getPMRequestType() != kIOPMRequestTypeActivityTickle) &&
2880 		    (fActivityTicklePowerState != kInvalidTicklePowerState)) {
2881 			IOLockLock(fActivityLock);
2882 			fActivityTicklePowerState = kInvalidTicklePowerState;
2883 			IOLockUnlock(fActivityLock);
2884 		}
2885 	}
2886 }
2887 
2888 //*********************************************************************************
2889 // [public] currentPowerConsumption
2890 //
2891 //*********************************************************************************
2892 
2893 unsigned long
currentPowerConsumption(void)2894 IOService::currentPowerConsumption( void )
2895 {
2896 	if (!initialized) {
2897 		return kIOPMUnknown;
2898 	}
2899 
2900 	return fCurrentPowerConsumption;
2901 }
2902 
2903 //*********************************************************************************
2904 // [deprecated] getPMworkloop
2905 //*********************************************************************************
2906 
2907 #ifndef __LP64__
2908 IOWorkLoop *
getPMworkloop(void)2909 IOService::getPMworkloop( void )
2910 {
2911 	return gIOPMWorkLoop;
2912 }
2913 #endif
2914 
2915 #if NOT_YET
2916 
2917 //*********************************************************************************
2918 // Power Parent/Children Applier
2919 //*********************************************************************************
2920 
2921 static void
applyToPowerChildren(IOService * service,IOServiceApplierFunction applier,void * context,IOOptionBits options)2922 applyToPowerChildren(
2923 	IOService *               service,
2924 	IOServiceApplierFunction  applier,
2925 	void *                    context,
2926 	IOOptionBits              options )
2927 {
2928 	PM_ASSERT_IN_GATE();
2929 
2930 	IORegistryEntry *       entry;
2931 	IORegistryIterator *    iter;
2932 	IOPowerConnection *     connection;
2933 	IOService *             child;
2934 
2935 	iter = IORegistryIterator::iterateOver(service, gIOPowerPlane, options);
2936 	if (iter) {
2937 		while ((entry = iter->getNextObject())) {
2938 			// Get child of IOPowerConnection objects
2939 			if ((connection = OSDynamicCast(IOPowerConnection, entry))) {
2940 				child = (IOService *) connection->copyChildEntry(gIOPowerPlane);
2941 				if (child) {
2942 					(*applier)(child, context);
2943 					child->release();
2944 				}
2945 			}
2946 		}
2947 		iter->release();
2948 	}
2949 }
2950 
2951 static void
applyToPowerParent(IOService * service,IOServiceApplierFunction applier,void * context,IOOptionBits options)2952 applyToPowerParent(
2953 	IOService *               service,
2954 	IOServiceApplierFunction  applier,
2955 	void *                    context,
2956 	IOOptionBits              options )
2957 {
2958 	PM_ASSERT_IN_GATE();
2959 
2960 	IORegistryEntry *       entry;
2961 	IORegistryIterator *    iter;
2962 	IOPowerConnection *     connection;
2963 	IOService *             parent;
2964 
2965 	iter = IORegistryIterator::iterateOver(service, gIOPowerPlane,
2966 	    options | kIORegistryIterateParents);
2967 	if (iter) {
2968 		while ((entry = iter->getNextObject())) {
2969 			// Get child of IOPowerConnection objects
2970 			if ((connection = OSDynamicCast(IOPowerConnection, entry))) {
2971 				parent = (IOService *) connection->copyParentEntry(gIOPowerPlane);
2972 				if (parent) {
2973 					(*applier)(parent, context);
2974 					parent->release();
2975 				}
2976 			}
2977 		}
2978 		iter->release();
2979 	}
2980 }
2981 
2982 #endif /* NOT_YET */
2983 
2984 // MARK: -
2985 // MARK: Activity Tickle & Idle Timer
2986 
2987 void
setAdvisoryTickleEnable(bool enable)2988 IOService::setAdvisoryTickleEnable( bool enable )
2989 {
2990 	gIOPMAdvisoryTickleEnabled = enable;
2991 }
2992 
2993 //*********************************************************************************
2994 // [public] activityTickle
2995 //
2996 // The tickle with parameter kIOPMSuperclassPolicy1 causes the activity
2997 // flag to be set, and the device state checked.  If the device has been
2998 // powered down, it is powered up again.
2999 // The tickle with parameter kIOPMSubclassPolicy is ignored here and
3000 // should be intercepted by a subclass.
3001 //*********************************************************************************
3002 
3003 bool
activityTickle(unsigned long type,unsigned long stateNumber)3004 IOService::activityTickle( unsigned long type, unsigned long stateNumber )
3005 {
3006 	if (!initialized) {
3007 		return true; // no power change
3008 	}
3009 
3010 	if (!fPowerStates) {
3011 		// registerPowerDriver may not have completed
3012 		IOPMRequest *   request;
3013 
3014 		request = acquirePMRequest( this, kIOPMRequestTypeDeferredActivityTickle );
3015 		if (request) {
3016 			request->fArg0 = (void *)            type;
3017 			request->fArg1 = (void *)(uintptr_t) stateNumber;
3018 			submitPMRequest(request);
3019 		}
3020 		// Returns false if the activityTickle might cause a transition to a
3021 		// higher powered state. We don't know, so this seems safest.
3022 		return false;
3023 	}
3024 
3025 	return _activityTickle(type, stateNumber);
3026 }
3027 
3028 //*********************************************************************************
3029 // [private] handleDeferredActivityTickle
3030 //*********************************************************************************
3031 
3032 void
handleDeferredActivityTickle(IOPMRequest * request)3033 IOService::handleDeferredActivityTickle( IOPMRequest * request )
3034 {
3035 	unsigned long type        = (unsigned long) request->fArg1;
3036 	unsigned long stateNumber = (unsigned long) request->fArg2;
3037 
3038 	if (!fPowerStates) {
3039 		// registerPowerDriver was not called before activityTickle()
3040 		return;
3041 	}
3042 	(void) _activityTickle(type, stateNumber);
3043 }
3044 
3045 //*********************************************************************************
3046 // [private] _activityTickle
3047 //
3048 // The tickle with parameter kIOPMSuperclassPolicy1 causes the activity
3049 // flag to be set, and the device state checked.  If the device has been
3050 // powered down, it is powered up again.
3051 // The tickle with parameter kIOPMSubclassPolicy is ignored here and
3052 // should be intercepted by a subclass.
3053 //*********************************************************************************
3054 
3055 bool
_activityTickle(unsigned long type,unsigned long stateNumber)3056 IOService::_activityTickle( unsigned long type, unsigned long stateNumber )
3057 {
3058 	IOPMRequest *   request;
3059 	bool            noPowerChange = true;
3060 	uint32_t        tickleFlags;
3061 
3062 	if ((type == kIOPMSuperclassPolicy1) && StateOrder(stateNumber)) {
3063 		IOLockLock(fActivityLock);
3064 
3065 		// Record device activity for the idle timer handler.
3066 
3067 		fDeviceWasActive = true;
3068 		fActivityTickleCount++;
3069 		clock_get_uptime(&fDeviceActiveTimestamp);
3070 
3071 		PM_ACTION_TICKLE(actionActivityTickle);
3072 
3073 		// Record the last tickle power state.
3074 		// This helps to filter out redundant tickles as
3075 		// this function may be called from the data path.
3076 
3077 		if ((fActivityTicklePowerState == kInvalidTicklePowerState)
3078 		    || StateOrder(fActivityTicklePowerState) < StateOrder(stateNumber)) {
3079 			fActivityTicklePowerState = stateNumber;
3080 			noPowerChange = false;
3081 
3082 			tickleFlags = kTickleTypeActivity | kTickleTypePowerRise;
3083 			request = acquirePMRequest( this, kIOPMRequestTypeActivityTickle );
3084 			if (request) {
3085 				request->fArg0 = (void *)            stateNumber;
3086 				request->fArg1 = (void *)(uintptr_t) tickleFlags;
3087 				request->fArg2 = (void *)(uintptr_t) gIOPMTickleGeneration;
3088 				submitPMRequest(request);
3089 			}
3090 		}
3091 
3092 		IOLockUnlock(fActivityLock);
3093 	} else if ((type == kIOPMActivityTickleTypeAdvisory) &&
3094 	    ((stateNumber = fDeviceUsablePowerState) != kPowerStateZero)) {
3095 		IOLockLock(fActivityLock);
3096 
3097 		fAdvisoryTickled = true;
3098 
3099 		if (fAdvisoryTicklePowerState != stateNumber) {
3100 			fAdvisoryTicklePowerState = stateNumber;
3101 			noPowerChange = false;
3102 
3103 			tickleFlags = kTickleTypeAdvisory | kTickleTypePowerRise;
3104 			request = acquirePMRequest( this, kIOPMRequestTypeActivityTickle );
3105 			if (request) {
3106 				request->fArg0 = (void *)            stateNumber;
3107 				request->fArg1 = (void *)(uintptr_t) tickleFlags;
3108 				request->fArg2 = (void *)(uintptr_t) gIOPMTickleGeneration;
3109 				submitPMRequest(request);
3110 			}
3111 		}
3112 
3113 		IOLockUnlock(fActivityLock);
3114 	}
3115 
3116 	// Returns false if the activityTickle might cause a transition to a
3117 	// higher powered state, true otherwise.
3118 
3119 	return noPowerChange;
3120 }
3121 
3122 //*********************************************************************************
3123 // [private] handleActivityTickle
3124 //*********************************************************************************
3125 
3126 void
handleActivityTickle(IOPMRequest * request)3127 IOService::handleActivityTickle( IOPMRequest * request )
3128 {
3129 	IOPMPowerStateIndex ticklePowerState = (IOPMPowerStateIndex) request->fArg0;
3130 	IOPMPowerStateIndex tickleFlags      = (IOPMPowerStateIndex) request->fArg1;
3131 	uint32_t            tickleGeneration = (uint32_t)(uintptr_t) request->fArg2;
3132 	bool adjustPower = false;
3133 
3134 	PM_ASSERT_IN_GATE();
3135 	if (fResetPowerStateOnWake && (tickleGeneration != gIOPMTickleGeneration)) {
3136 		// Drivers that don't want power restored on wake will drop any
3137 		// tickles that pre-dates the current system wake. The model is
3138 		// that each wake is a fresh start, with power state depressed
3139 		// until a new tickle or an explicit power up request from the
3140 		// driver. It is possible for the PM work loop to enter the
3141 		// system sleep path with tickle requests queued.
3142 
3143 		return;
3144 	}
3145 
3146 	if (tickleFlags & kTickleTypeActivity) {
3147 		IOPMPowerStateIndex deviceDesireOrder = StateOrder(fDeviceDesire);
3148 		IOPMPowerStateIndex idleTimerGeneration = ticklePowerState; // kTickleTypePowerDrop
3149 
3150 		if (tickleFlags & kTickleTypePowerRise) {
3151 			if ((StateOrder(ticklePowerState) > deviceDesireOrder) &&
3152 			    (ticklePowerState < fNumberOfPowerStates)) {
3153 				fIdleTimerMinPowerState = ticklePowerState;
3154 				updatePowerClient(gIOPMPowerClientDevice, ticklePowerState);
3155 				adjustPower = true;
3156 			}
3157 		} else if ((deviceDesireOrder > StateOrder(fIdleTimerMinPowerState)) &&
3158 		    (idleTimerGeneration == fIdleTimerGeneration)) {
3159 			// Power drop due to idle timer expiration.
3160 			// Do not allow idle timer to reduce power below tickle power.
3161 			// This prevents the idle timer from decreasing the device desire
3162 			// to zero and cancelling the effect of a pre-sleep tickle when
3163 			// system wakes up to doze state, while the device is unable to
3164 			// raise its power state to satisfy the tickle.
3165 
3166 			deviceDesireOrder--;
3167 			if (deviceDesireOrder < fNumberOfPowerStates) {
3168 				ticklePowerState = fPowerStates[deviceDesireOrder].stateOrderToIndex;
3169 				updatePowerClient(gIOPMPowerClientDevice, ticklePowerState);
3170 				adjustPower = true;
3171 			}
3172 		}
3173 	} else { // advisory tickle
3174 		if (tickleFlags & kTickleTypePowerRise) {
3175 			if ((ticklePowerState == fDeviceUsablePowerState) &&
3176 			    (ticklePowerState < fNumberOfPowerStates)) {
3177 				updatePowerClient(gIOPMPowerClientAdvisoryTickle, ticklePowerState);
3178 				fHasAdvisoryDesire = true;
3179 				fAdvisoryTickleUsed = true;
3180 				adjustPower = true;
3181 			} else {
3182 				IOLockLock(fActivityLock);
3183 				fAdvisoryTicklePowerState = kInvalidTicklePowerState;
3184 				IOLockUnlock(fActivityLock);
3185 			}
3186 		} else if (fHasAdvisoryDesire) {
3187 			removePowerClient(gIOPMPowerClientAdvisoryTickle);
3188 			fHasAdvisoryDesire = false;
3189 			adjustPower = true;
3190 		}
3191 	}
3192 
3193 	if (adjustPower) {
3194 		adjustPowerState();
3195 	}
3196 }
3197 
3198 //******************************************************************************
3199 // [public] setIdleTimerPeriod
3200 //
3201 // A subclass policy-maker is using our standard idleness detection service.
3202 // Start the idle timer. Period is in seconds.
3203 //******************************************************************************
3204 
3205 IOReturn
setIdleTimerPeriod(unsigned long period)3206 IOService::setIdleTimerPeriod( unsigned long period )
3207 {
3208 	if (!initialized) {
3209 		return IOPMNotYetInitialized;
3210 	}
3211 
3212 	OUR_PMLog(kPMLogSetIdleTimerPeriod, period, fIdleTimerPeriod);
3213 
3214 	if (period > INT_MAX) {
3215 		return kIOReturnBadArgument;
3216 	}
3217 
3218 	IOPMRequest * request =
3219 	    acquirePMRequest( this, kIOPMRequestTypeSetIdleTimerPeriod );
3220 	if (!request) {
3221 		return kIOReturnNoMemory;
3222 	}
3223 
3224 	request->fArg0 = (void *) period;
3225 	submitPMRequest( request );
3226 
3227 	return kIOReturnSuccess;
3228 }
3229 
3230 IOReturn
setIgnoreIdleTimer(bool ignore)3231 IOService::setIgnoreIdleTimer( bool ignore )
3232 {
3233 	if (!initialized) {
3234 		return IOPMNotYetInitialized;
3235 	}
3236 
3237 	OUR_PMLog(kIOPMRequestTypeIgnoreIdleTimer, ignore, 0);
3238 
3239 	IOPMRequest * request =
3240 	    acquirePMRequest( this, kIOPMRequestTypeIgnoreIdleTimer );
3241 	if (!request) {
3242 		return kIOReturnNoMemory;
3243 	}
3244 
3245 	request->fArg0 = (void *) ignore;
3246 	submitPMRequest( request );
3247 
3248 	return kIOReturnSuccess;
3249 }
3250 
3251 //******************************************************************************
3252 // [public] nextIdleTimeout
3253 //
3254 // Returns how many "seconds from now" the device should idle into its
3255 // next lowest power state.
3256 //******************************************************************************
3257 
3258 SInt32
nextIdleTimeout(AbsoluteTime currentTime,AbsoluteTime lastActivity,unsigned int powerState)3259 IOService::nextIdleTimeout(
3260 	AbsoluteTime currentTime,
3261 	AbsoluteTime lastActivity,
3262 	unsigned int powerState)
3263 {
3264 	AbsoluteTime        delta;
3265 	UInt64              delta_ns;
3266 	SInt32              delta_secs;
3267 	SInt32              delay_secs;
3268 
3269 	// Calculate time difference using funky macro from clock.h.
3270 	delta = currentTime;
3271 	SUB_ABSOLUTETIME(&delta, &lastActivity);
3272 
3273 	// Figure it in seconds.
3274 	absolutetime_to_nanoseconds(delta, &delta_ns);
3275 	delta_secs = (SInt32)(delta_ns / NSEC_PER_SEC);
3276 
3277 	// Be paranoid about delta somehow exceeding timer period.
3278 	if (delta_secs < (int) fIdleTimerPeriod) {
3279 		delay_secs = (int) fIdleTimerPeriod - delta_secs;
3280 	} else {
3281 		delay_secs = (int) fIdleTimerPeriod;
3282 	}
3283 
3284 	return (SInt32)delay_secs;
3285 }
3286 
3287 //*********************************************************************************
3288 // [public] start_PM_idle_timer
3289 //*********************************************************************************
3290 
3291 void
start_PM_idle_timer(void)3292 IOService::start_PM_idle_timer( void )
3293 {
3294 	static const int    maxTimeout = 100000;
3295 	static const int    minTimeout = 1;
3296 	AbsoluteTime        uptime, deadline;
3297 	SInt32              idle_in = 0;
3298 	boolean_t           pending;
3299 
3300 	if (!initialized || !fIdleTimerPeriod ||
3301 	    ((unsigned int) fCurrentPowerState != fCurrentPowerState)) {
3302 		return;
3303 	}
3304 
3305 	IOLockLock(fActivityLock);
3306 
3307 	clock_get_uptime(&uptime);
3308 
3309 	// Subclasses may modify idle sleep algorithm
3310 	idle_in = nextIdleTimeout(uptime, fDeviceActiveTimestamp, (unsigned int) fCurrentPowerState);
3311 
3312 	// Check for out-of range responses
3313 	if (idle_in > maxTimeout) {
3314 		// use standard implementation
3315 		idle_in = IOService::nextIdleTimeout(uptime,
3316 		    fDeviceActiveTimestamp,
3317 		    (unsigned int) fCurrentPowerState);
3318 	} else if (idle_in < minTimeout) {
3319 		idle_in = fIdleTimerPeriod;
3320 	}
3321 
3322 	IOLockUnlock(fActivityLock);
3323 
3324 	fNextIdleTimerPeriod = idle_in;
3325 	fIdleTimerStartTime = uptime;
3326 
3327 	retain();
3328 	clock_interval_to_absolutetime_interval(idle_in, kSecondScale, &deadline);
3329 	ADD_ABSOLUTETIME(&deadline, &uptime);
3330 	pending = thread_call_enter_delayed(fIdleTimer, deadline);
3331 	if (pending) {
3332 		release();
3333 	}
3334 }
3335 
3336 //*********************************************************************************
3337 // [private] restartIdleTimer
3338 //*********************************************************************************
3339 
3340 void
restartIdleTimer(void)3341 IOService::restartIdleTimer( void )
3342 {
3343 	if (fDeviceDesire != kPowerStateZero) {
3344 		fIdleTimerStopped = false;
3345 		fActivityTickleCount = 0;
3346 		start_PM_idle_timer();
3347 	} else if (fHasAdvisoryDesire) {
3348 		fIdleTimerStopped = false;
3349 		start_PM_idle_timer();
3350 	} else {
3351 		fIdleTimerStopped = true;
3352 	}
3353 }
3354 
3355 //*********************************************************************************
3356 // idle_timer_expired
3357 //*********************************************************************************
3358 
3359 static void
idle_timer_expired(thread_call_param_t arg0,thread_call_param_t arg1)3360 idle_timer_expired(
3361 	thread_call_param_t arg0, thread_call_param_t arg1 )
3362 {
3363 	IOService * me = (IOService *) arg0;
3364 
3365 	if (gIOPMWorkLoop) {
3366 		gIOPMWorkLoop->runAction(
3367 			OSMemberFunctionCast(IOWorkLoop::Action, me,
3368 			&IOService::idleTimerExpired),
3369 			me);
3370 	}
3371 
3372 	me->release();
3373 }
3374 
3375 //*********************************************************************************
3376 // [private] idleTimerExpired
3377 //
3378 // The idle timer has expired. If there has been activity since the last
3379 // expiration, just restart the timer and return.  If there has not been
3380 // activity, switch to the next lower power state and restart the timer.
3381 //*********************************************************************************
3382 
3383 void
idleTimerExpired(void)3384 IOService::idleTimerExpired( void )
3385 {
3386 	IOPMRequest *   request;
3387 	bool            restartTimer = true;
3388 	uint32_t        tickleFlags;
3389 
3390 	if (!initialized || !fIdleTimerPeriod || fIdleTimerStopped ||
3391 	    fLockedFlags.PMStop) {
3392 		return;
3393 	}
3394 
3395 	fIdleTimerStartTime = 0;
3396 
3397 	IOLockLock(fActivityLock);
3398 
3399 	// Check for device activity (tickles) over last timer period.
3400 
3401 	if (fDeviceWasActive) {
3402 		// Device was active - do not drop power, restart timer.
3403 		fDeviceWasActive = false;
3404 	} else if (!fIdleTimerIgnored) {
3405 		// No device activity - drop power state by one level.
3406 		// Decrement the cached tickle power state when possible.
3407 		// This value may be kInvalidTicklePowerState before activityTickle()
3408 		// is called, but the power drop request must be issued regardless.
3409 
3410 		if ((fActivityTicklePowerState != kInvalidTicklePowerState) &&
3411 		    (fActivityTicklePowerState != kPowerStateZero)) {
3412 			fActivityTicklePowerState--;
3413 		}
3414 
3415 		tickleFlags = kTickleTypeActivity | kTickleTypePowerDrop;
3416 		request = acquirePMRequest( this, kIOPMRequestTypeActivityTickle );
3417 		if (request) {
3418 			request->fArg0 = (void *)(uintptr_t) fIdleTimerGeneration;
3419 			request->fArg1 = (void *)(uintptr_t) tickleFlags;
3420 			request->fArg2 = (void *)(uintptr_t) gIOPMTickleGeneration;
3421 			submitPMRequest( request );
3422 
3423 			// Do not restart timer until after the tickle request has been
3424 			// processed.
3425 
3426 			restartTimer = false;
3427 		}
3428 	}
3429 
3430 	if (fAdvisoryTickled) {
3431 		fAdvisoryTickled = false;
3432 	} else if (fHasAdvisoryDesire) {
3433 		// Want new tickles to turn into pm request after we drop the lock
3434 		fAdvisoryTicklePowerState = kInvalidTicklePowerState;
3435 
3436 		tickleFlags = kTickleTypeAdvisory | kTickleTypePowerDrop;
3437 		request = acquirePMRequest( this, kIOPMRequestTypeActivityTickle );
3438 		if (request) {
3439 			request->fArg0 = (void *)(uintptr_t) fIdleTimerGeneration;
3440 			request->fArg1 = (void *)(uintptr_t) tickleFlags;
3441 			request->fArg2 = (void *)(uintptr_t) gIOPMTickleGeneration;
3442 			submitPMRequest( request );
3443 
3444 			// Do not restart timer until after the tickle request has been
3445 			// processed.
3446 
3447 			restartTimer = false;
3448 		}
3449 	}
3450 
3451 	IOLockUnlock(fActivityLock);
3452 
3453 	if (restartTimer) {
3454 		start_PM_idle_timer();
3455 	}
3456 }
3457 
3458 #ifndef __LP64__
3459 //*********************************************************************************
3460 // [deprecated] PM_idle_timer_expiration
3461 //*********************************************************************************
3462 
3463 void
PM_idle_timer_expiration(void)3464 IOService::PM_idle_timer_expiration( void )
3465 {
3466 }
3467 
3468 //*********************************************************************************
3469 // [deprecated] command_received
3470 //*********************************************************************************
3471 
3472 void
command_received(void * statePtr,void *,void *,void *)3473 IOService::command_received( void *statePtr, void *, void *, void * )
3474 {
3475 }
3476 #endif /* !__LP64__ */
3477 
3478 //*********************************************************************************
3479 // [public] setAggressiveness
3480 //
3481 // Pass on the input parameters to all power domain children. All those which are
3482 // power domains will pass it on to their children, etc.
3483 //*********************************************************************************
3484 
3485 IOReturn
setAggressiveness(unsigned long type,unsigned long newLevel)3486 IOService::setAggressiveness( unsigned long type, unsigned long newLevel )
3487 {
3488 	return kIOReturnSuccess;
3489 }
3490 
3491 //*********************************************************************************
3492 // [public] getAggressiveness
3493 //
3494 // Called by the user client.
3495 //*********************************************************************************
3496 
3497 IOReturn
getAggressiveness(unsigned long type,unsigned long * currentLevel)3498 IOService::getAggressiveness( unsigned long type, unsigned long * currentLevel )
3499 {
3500 	IOPMrootDomain *    rootDomain = getPMRootDomain();
3501 
3502 	if (!rootDomain) {
3503 		return kIOReturnNotReady;
3504 	}
3505 
3506 	return rootDomain->getAggressiveness( type, currentLevel );
3507 }
3508 
3509 //*********************************************************************************
3510 // [public] getPowerState
3511 //
3512 //*********************************************************************************
3513 
3514 UInt32
getPowerState(void)3515 IOService::getPowerState( void )
3516 {
3517 	if (!initialized) {
3518 		return kPowerStateZero;
3519 	}
3520 
3521 	return (UInt32) fCurrentPowerState;
3522 }
3523 
3524 #ifndef __LP64__
3525 //*********************************************************************************
3526 // [deprecated] systemWake
3527 //
3528 // Pass this to all power domain children. All those which are
3529 // power domains will pass it on to their children, etc.
3530 //*********************************************************************************
3531 
3532 IOReturn
systemWake(void)3533 IOService::systemWake( void )
3534 {
3535 	OSIterator *        iter;
3536 	OSObject *          next;
3537 	IOPowerConnection * connection;
3538 	IOService *         theChild;
3539 
3540 	iter = getChildIterator(gIOPowerPlane);
3541 	if (iter) {
3542 		while ((next = iter->getNextObject())) {
3543 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
3544 				if (connection->getReadyFlag() == false) {
3545 					PM_LOG3("[%s] %s: connection not ready\n",
3546 					    getName(), __FUNCTION__);
3547 					continue;
3548 				}
3549 
3550 				theChild = (IOService *)connection->copyChildEntry(gIOPowerPlane);
3551 				if (theChild) {
3552 					theChild->systemWake();
3553 					theChild->release();
3554 				}
3555 			}
3556 		}
3557 		iter->release();
3558 	}
3559 
3560 	if (fControllingDriver != NULL) {
3561 		if (fControllingDriver->didYouWakeSystem()) {
3562 			makeUsable();
3563 		}
3564 	}
3565 
3566 	return IOPMNoErr;
3567 }
3568 
3569 //*********************************************************************************
3570 // [deprecated] temperatureCriticalForZone
3571 //*********************************************************************************
3572 
3573 IOReturn
temperatureCriticalForZone(IOService * whichZone)3574 IOService::temperatureCriticalForZone( IOService * whichZone )
3575 {
3576 	IOService * theParent;
3577 	IOService * theNub;
3578 
3579 	OUR_PMLog(kPMLogCriticalTemp, 0, 0);
3580 
3581 	if (inPlane(gIOPowerPlane) && !IS_PM_ROOT) {
3582 		theNub = (IOService *)copyParentEntry(gIOPowerPlane);
3583 		if (theNub) {
3584 			theParent = (IOService *)theNub->copyParentEntry(gIOPowerPlane);
3585 			theNub->release();
3586 			if (theParent) {
3587 				theParent->temperatureCriticalForZone(whichZone);
3588 				theParent->release();
3589 			}
3590 		}
3591 	}
3592 	return IOPMNoErr;
3593 }
3594 #endif /* !__LP64__ */
3595 
3596 // MARK: -
3597 // MARK: Power Change (Common)
3598 
3599 //*********************************************************************************
3600 // [private] startPowerChange
3601 //
3602 // All power state changes starts here.
3603 //*********************************************************************************
3604 
3605 IOReturn
startPowerChange(IOPMPowerChangeFlags changeFlags,IOPMPowerStateIndex powerState,IOPMPowerFlags domainFlags,IOPowerConnection * parentConnection,IOPMPowerFlags parentFlags)3606 IOService::startPowerChange(
3607 	IOPMPowerChangeFlags    changeFlags,
3608 	IOPMPowerStateIndex     powerState,
3609 	IOPMPowerFlags          domainFlags,
3610 	IOPowerConnection *     parentConnection,
3611 	IOPMPowerFlags          parentFlags )
3612 {
3613 	uint32_t savedPMActionsState;
3614 
3615 	PM_ASSERT_IN_GATE();
3616 	assert( fMachineState == kIOPM_Finished );
3617 	assert( powerState < fNumberOfPowerStates );
3618 
3619 	if (powerState >= fNumberOfPowerStates) {
3620 		return IOPMAckImplied;
3621 	}
3622 
3623 	fIsPreChange = true;
3624 	savedPMActionsState = fPMActions.state;
3625 	PM_ACTION_CHANGE(actionPowerChangeOverride, &powerState, &changeFlags);
3626 
3627 	// rdar://problem/55040032
3628 	// Schedule a power adjustment after removing the power clamp
3629 	// to inform our power parent(s) about our latest desired domain
3630 	// power state. For a self-initiated change, let OurChangeStart()
3631 	// automatically request parent power when necessary.
3632 	if (!fAdjustPowerScheduled &&
3633 	    ((changeFlags & kIOPMSelfInitiated) == 0) &&
3634 	    ((fPMActions.state & kPMActionsStatePowerClamped) == 0) &&
3635 	    ((savedPMActionsState & kPMActionsStatePowerClamped) != 0)) {
3636 		IOPMRequest * request = acquirePMRequest(this, kIOPMRequestTypeAdjustPowerState);
3637 		if (request) {
3638 			submitPMRequest(request);
3639 			fAdjustPowerScheduled = true;
3640 		}
3641 	}
3642 
3643 	if (changeFlags & kIOPMExpireIdleTimer) {
3644 		// Root domain requested removal of tickle influence
3645 		if (StateOrder(fDeviceDesire) > StateOrder(powerState)) {
3646 			// Reset device desire down to the clamped power state
3647 			updatePowerClient(gIOPMPowerClientDevice, powerState);
3648 			computeDesiredState(kPowerStateZero, true);
3649 
3650 			// Invalidate tickle cache so the next tickle will issue a request
3651 			IOLockLock(fActivityLock);
3652 			fDeviceWasActive = false;
3653 			fActivityTicklePowerState = kInvalidTicklePowerState;
3654 			IOLockUnlock(fActivityLock);
3655 
3656 			fIdleTimerMinPowerState = kPowerStateZero;
3657 		}
3658 	}
3659 
3660 	// Root domain's override handler may cancel the power change by
3661 	// setting the kIOPMNotDone flag.
3662 
3663 	if (changeFlags & kIOPMNotDone) {
3664 		return IOPMAckImplied;
3665 	}
3666 
3667 	// Forks to either Driver or Parent initiated power change paths.
3668 
3669 	fHeadNoteChangeFlags      = changeFlags;
3670 	fHeadNotePowerState       = powerState;
3671 	fHeadNotePowerArrayEntry  = &fPowerStates[powerState];
3672 	fHeadNoteParentConnection = NULL;
3673 
3674 	if (changeFlags & kIOPMSelfInitiated) {
3675 		if (changeFlags & kIOPMSynchronize) {
3676 			OurSyncStart();
3677 		} else {
3678 			OurChangeStart();
3679 		}
3680 		return 0;
3681 	} else {
3682 		assert(changeFlags & kIOPMParentInitiated);
3683 		fHeadNoteDomainFlags = domainFlags;
3684 		fHeadNoteParentFlags = parentFlags;
3685 		fHeadNoteParentConnection = parentConnection;
3686 		return ParentChangeStart();
3687 	}
3688 }
3689 
3690 //*********************************************************************************
3691 // [private] notifyInterestedDrivers
3692 //*********************************************************************************
3693 
3694 bool
notifyInterestedDrivers(void)3695 IOService::notifyInterestedDrivers( void )
3696 {
3697 	IOPMinformee *      informee;
3698 	IOPMinformeeList *  list = fInterestedDrivers;
3699 	DriverCallParam *   param;
3700 	unsigned long       numItems;
3701 	uint32_t            count;
3702 	uint32_t            skipCnt = 0;
3703 
3704 	PM_ASSERT_IN_GATE();
3705 	assert( fDriverCallParamCount == 0 );
3706 	assert( fHeadNotePendingAcks == 0 );
3707 
3708 	fHeadNotePendingAcks = 0;
3709 
3710 	numItems = list->numberOfItems();
3711 	if (!numItems || ((uint32_t) numItems != numItems)) {
3712 		goto done; // interested drivers count out of range
3713 	}
3714 	count = (uint32_t) numItems;
3715 
3716 	// Allocate an array of interested drivers and their return values
3717 	// for the callout thread. Everything else is still "owned" by the
3718 	// PM work loop, which can run to process acknowledgePowerChange()
3719 	// responses.
3720 
3721 	param = (DriverCallParam *) fDriverCallParamPtr;
3722 	if (count > fDriverCallParamSlots) {
3723 		if (fDriverCallParamSlots) {
3724 			assert(fDriverCallParamPtr);
3725 			IODelete(fDriverCallParamPtr, DriverCallParam, fDriverCallParamSlots);
3726 			fDriverCallParamPtr = NULL;
3727 			fDriverCallParamSlots = 0;
3728 		}
3729 
3730 		param = IONew(DriverCallParam, count);
3731 		if (!param) {
3732 			goto done; // no memory
3733 		}
3734 		fDriverCallParamPtr   = (void *) param;
3735 		fDriverCallParamSlots = count;
3736 	}
3737 
3738 	informee = list->firstInList();
3739 	assert(informee);
3740 	for (IOItemCount i = 0, arrayIdx = 0; i < count; i++) {
3741 		if (fInitialSetPowerState || (fHeadNoteChangeFlags & kIOPMInitialPowerChange)) {
3742 			// Skip notifying self, if 'kIOPMInitialDeviceState' is set and
3743 			// this is the initial power state change
3744 			if ((this == informee->whatObject) &&
3745 			    (fHeadNotePowerArrayEntry->capabilityFlags & kIOPMInitialDeviceState)) {
3746 				skipCnt++;
3747 				continue;
3748 			}
3749 		}
3750 		informee->timer = -1;
3751 		param[arrayIdx].Target = informee;
3752 		informee->retain();
3753 		informee = list->nextInList( informee );
3754 		arrayIdx++;
3755 	}
3756 
3757 	count -= skipCnt;
3758 	if (!count) {
3759 		goto done;
3760 	}
3761 	fDriverCallParamCount = count;
3762 	fHeadNotePendingAcks  = count;
3763 
3764 	// Block state machine and wait for callout completion.
3765 	assert(!fDriverCallBusy);
3766 	fDriverCallBusy = true;
3767 	thread_call_enter( fDriverCallEntry );
3768 	return true;
3769 
3770 done:
3771 	// Return false if there are no interested drivers or could not schedule
3772 	// callout thread due to error.
3773 	return false;
3774 }
3775 
3776 //*********************************************************************************
3777 // [private] notifyInterestedDriversDone
3778 //*********************************************************************************
3779 
3780 void
notifyInterestedDriversDone(void)3781 IOService::notifyInterestedDriversDone( void )
3782 {
3783 	IOPMinformee *      informee;
3784 	IOItemCount         count;
3785 	DriverCallParam *   param;
3786 	IOReturn            result;
3787 	int                 maxTimeout = 0;
3788 
3789 	PM_ASSERT_IN_GATE();
3790 	assert( fDriverCallBusy == false );
3791 	assert( fMachineState == kIOPM_DriverThreadCallDone );
3792 
3793 	param = (DriverCallParam *) fDriverCallParamPtr;
3794 	count = fDriverCallParamCount;
3795 
3796 	if (param && count) {
3797 		for (IOItemCount i = 0; i < count; i++, param++) {
3798 			informee = (IOPMinformee *) param->Target;
3799 			result   = param->Result;
3800 
3801 			if ((result == IOPMAckImplied) || (result < 0)) {
3802 				// Interested driver return IOPMAckImplied.
3803 				// If informee timer is zero, it must have de-registered
3804 				// interest during the thread callout. That also drops
3805 				// the pending ack count.
3806 
3807 				if (fHeadNotePendingAcks && informee->timer) {
3808 					fHeadNotePendingAcks--;
3809 				}
3810 
3811 				informee->timer = 0;
3812 			} else if (informee->timer) {
3813 				assert(informee->timer == -1);
3814 
3815 				// Driver has not acked, and has returned a positive result.
3816 				// Enforce a minimum permissible timeout value.
3817 				// Make the min value large enough so timeout is less likely
3818 				// to occur if a driver misinterpreted that the return value
3819 				// should be in microsecond units.  And make it large enough
3820 				// to be noticeable if a driver neglects to ack.
3821 
3822 				if (result < kMinAckTimeoutTicks) {
3823 					result = kMinAckTimeoutTicks;
3824 				}
3825 
3826 				informee->timer = (result / (ACK_TIMER_PERIOD / ns_per_us)) + 1;
3827 				if (result > maxTimeout) {
3828 					maxTimeout = result;
3829 				}
3830 			}
3831 			// else, child has already acked or driver has removed interest,
3832 			// and head_note_pendingAcks decremented.
3833 			// informee may have been removed from the interested drivers list,
3834 			// thus the informee must be retained across the callout.
3835 
3836 			informee->release();
3837 		}
3838 
3839 		fDriverCallParamCount = 0;
3840 
3841 		if (fHeadNotePendingAcks) {
3842 			OUR_PMLog(kPMLogStartAckTimer, 0, 0);
3843 			start_ack_timer();
3844 			getPMRootDomain()->reset_watchdog_timer(this, maxTimeout / USEC_PER_SEC + 1);
3845 		}
3846 	}
3847 
3848 	MS_POP(); // pop the machine state passed to notifyAll()
3849 
3850 	// If interest acks are outstanding, block the state machine until
3851 	// fHeadNotePendingAcks drops to zero before notifying root domain.
3852 	// Otherwise notify root domain directly.
3853 
3854 	if (!fHeadNotePendingAcks) {
3855 		notifyRootDomain();
3856 	} else {
3857 		MS_PUSH(fMachineState);
3858 		fMachineState = kIOPM_NotifyChildrenStart;
3859 	}
3860 }
3861 
3862 //*********************************************************************************
3863 // [private] notifyRootDomain
3864 //*********************************************************************************
3865 
3866 void
notifyRootDomain(void)3867 IOService::notifyRootDomain( void )
3868 {
3869 	assert( fDriverCallBusy == false );
3870 
3871 	// Only for root domain in the will-change phase.
3872 	// On a power up, don't notify children right after the interested drivers.
3873 	// Perform setPowerState() first, then notify the children.
3874 	if (!IS_ROOT_DOMAIN || (fMachineState != kIOPM_OurChangeSetPowerState)) {
3875 		notifyChildren();
3876 		return;
3877 	}
3878 
3879 	MS_PUSH(fMachineState); // push notifyAll() machine state
3880 	fMachineState = kIOPM_DriverThreadCallDone;
3881 
3882 	// Call IOPMrootDomain::willNotifyPowerChildren() on a thread call
3883 	// to avoid a deadlock.
3884 	fDriverCallReason = kRootDomainInformPreChange;
3885 	fDriverCallBusy   = true;
3886 	thread_call_enter( fDriverCallEntry );
3887 }
3888 
3889 void
notifyRootDomainDone(void)3890 IOService::notifyRootDomainDone( void )
3891 {
3892 	assert( fDriverCallBusy == false );
3893 	assert( fMachineState == kIOPM_DriverThreadCallDone );
3894 
3895 	MS_POP(); // pop notifyAll() machine state
3896 	notifyChildren();
3897 }
3898 
3899 //*********************************************************************************
3900 // [private] notifyChildren
3901 //*********************************************************************************
3902 
3903 void
notifyChildren(void)3904 IOService::notifyChildren( void )
3905 {
3906 	OSIterator *        iter;
3907 	OSObject *          next;
3908 	IOPowerConnection * connection;
3909 	OSArray *           children = NULL;
3910 	IOPMrootDomain *    rootDomain;
3911 	bool                delayNotify = false;
3912 
3913 	if ((fHeadNotePowerState != fCurrentPowerState) &&
3914 	    (IS_POWER_DROP == fIsPreChange) &&
3915 	    ((rootDomain = getPMRootDomain()) == this)) {
3916 		rootDomain->tracePoint( IS_POWER_DROP ?
3917 		    kIOPMTracePointSleepPowerPlaneDrivers :
3918 		    kIOPMTracePointWakePowerPlaneDrivers  );
3919 	}
3920 
3921 	if (fStrictTreeOrder) {
3922 		children = OSArray::withCapacity(8);
3923 	}
3924 
3925 	// Sum child power consumption in notifyChild()
3926 	fHeadNotePowerArrayEntry->staticPower = 0;
3927 
3928 	iter = getChildIterator(gIOPowerPlane);
3929 	if (iter) {
3930 		while ((next = iter->getNextObject())) {
3931 			if ((connection = OSDynamicCast(IOPowerConnection, next))) {
3932 				if (connection->getReadyFlag() == false) {
3933 					PM_LOG3("[%s] %s: connection not ready\n",
3934 					    getName(), __FUNCTION__);
3935 					continue;
3936 				}
3937 
3938 				// Mechanism to postpone the did-change notification to
3939 				// certain power children to order those children last.
3940 				// Cannot be used together with strict tree ordering.
3941 
3942 				if (!fIsPreChange &&
3943 				    connection->delayChildNotification &&
3944 				    getPMRootDomain()->shouldDelayChildNotification(this)) {
3945 					if (!children) {
3946 						children = OSArray::withCapacity(8);
3947 						if (children) {
3948 							delayNotify = true;
3949 						}
3950 					}
3951 					if (delayNotify) {
3952 						children->setObject( connection );
3953 						continue;
3954 					}
3955 				}
3956 
3957 				if (!delayNotify && children) {
3958 					children->setObject( connection );
3959 				} else {
3960 					notifyChild( connection );
3961 				}
3962 			}
3963 		}
3964 		iter->release();
3965 	}
3966 
3967 	if (children && (children->getCount() == 0)) {
3968 		children->release();
3969 		children = NULL;
3970 	}
3971 	if (children) {
3972 		assert(fNotifyChildArray == NULL);
3973 		fNotifyChildArray = children;
3974 		MS_PUSH(fMachineState);
3975 
3976 		if (delayNotify) {
3977 			// Block until all non-delayed children have acked their
3978 			// notification. Then notify the remaining delayed child
3979 			// in the array. This is used to hold off graphics child
3980 			// notification while the rest of the system powers up.
3981 			// If a hid tickle arrives during this time, the delayed
3982 			// children are immediately notified and root domain will
3983 			// not clamp power for dark wake.
3984 
3985 			fMachineState = kIOPM_NotifyChildrenDelayed;
3986 			PM_LOG2("%s: %d children in delayed array\n",
3987 			    getName(), children->getCount());
3988 		} else {
3989 			// Child array created to support strict notification order.
3990 			// Notify children in the array one at a time.
3991 
3992 			fMachineState = kIOPM_NotifyChildrenOrdered;
3993 		}
3994 	}
3995 }
3996 
3997 //*********************************************************************************
3998 // [private] notifyChildrenOrdered
3999 //*********************************************************************************
4000 
4001 void
notifyChildrenOrdered(void)4002 IOService::notifyChildrenOrdered( void )
4003 {
4004 	PM_ASSERT_IN_GATE();
4005 	assert(fNotifyChildArray);
4006 	assert(fMachineState == kIOPM_NotifyChildrenOrdered);
4007 
4008 	// Notify one child, wait for it to ack, then repeat for next child.
4009 	// This is a workaround for some drivers with multiple instances at
4010 	// the same branch in the power tree, but the driver is slow to power
4011 	// up unless the tree ordering is observed. Problem observed only on
4012 	// system wake, not on system sleep.
4013 	//
4014 	// We have the ability to power off in reverse child index order.
4015 	// That works nicely on some machines, but not on all HW configs.
4016 
4017 	if (fNotifyChildArray->getCount()) {
4018 		IOPowerConnection * connection;
4019 		connection = (IOPowerConnection *) fNotifyChildArray->getObject(0);
4020 		notifyChild( connection );
4021 		fNotifyChildArray->removeObject(0);
4022 	} else {
4023 		fNotifyChildArray->release();
4024 		fNotifyChildArray = NULL;
4025 
4026 		MS_POP(); // pushed by notifyChildren()
4027 	}
4028 }
4029 
4030 //*********************************************************************************
4031 // [private] notifyChildrenDelayed
4032 //*********************************************************************************
4033 
4034 void
notifyChildrenDelayed(void)4035 IOService::notifyChildrenDelayed( void )
4036 {
4037 	IOPowerConnection * connection;
4038 
4039 	PM_ASSERT_IN_GATE();
4040 	assert(fNotifyChildArray);
4041 	assert(fMachineState == kIOPM_NotifyChildrenDelayed);
4042 
4043 	// Wait after all non-delayed children and interested drivers have ack'ed,
4044 	// then notify all delayed children. If notify delay is canceled, child
4045 	// acks may be outstanding with PM blocked on fHeadNotePendingAcks != 0.
4046 	// But the handling for either case is identical.
4047 
4048 	for (int i = 0;; i++) {
4049 		connection = (IOPowerConnection *) fNotifyChildArray->getObject(i);
4050 		if (!connection) {
4051 			break;
4052 		}
4053 
4054 		notifyChild( connection );
4055 	}
4056 
4057 	PM_LOG2("%s: notified delayed children\n", getName());
4058 	fNotifyChildArray->release();
4059 	fNotifyChildArray = NULL;
4060 
4061 	MS_POP(); // pushed by notifyChildren()
4062 }
4063 
4064 //*********************************************************************************
4065 // [private] notifyAll
4066 //*********************************************************************************
4067 
4068 IOReturn
notifyAll(uint32_t nextMS)4069 IOService::notifyAll( uint32_t nextMS )
4070 {
4071 	// Save the machine state to be restored by notifyInterestedDriversDone()
4072 
4073 	PM_ASSERT_IN_GATE();
4074 	MS_PUSH(nextMS);
4075 	fMachineState     = kIOPM_DriverThreadCallDone;
4076 	fDriverCallReason = fIsPreChange ?
4077 	    kDriverCallInformPreChange : kDriverCallInformPostChange;
4078 
4079 	if (!notifyInterestedDrivers()) {
4080 		notifyInterestedDriversDone();
4081 	}
4082 
4083 	return IOPMWillAckLater;
4084 }
4085 
4086 //*********************************************************************************
4087 // [private, static] pmDriverCallout
4088 //
4089 // Thread call context
4090 //*********************************************************************************
4091 
4092 IOReturn
actionDriverCalloutDone(OSObject * target,void * arg0,void * arg1,void * arg2,void * arg3)4093 IOService::actionDriverCalloutDone(
4094 	OSObject * target,
4095 	void * arg0, void * arg1,
4096 	void * arg2, void * arg3 )
4097 {
4098 	IOServicePM * pwrMgt = (IOServicePM *) arg0;
4099 
4100 	assert( fDriverCallBusy );
4101 	fDriverCallBusy = false;
4102 
4103 	assert(gIOPMWorkQueue);
4104 	gIOPMWorkQueue->signalWorkAvailable();
4105 
4106 	return kIOReturnSuccess;
4107 }
4108 
4109 void
pmDriverCallout(IOService * from)4110 IOService::pmDriverCallout( IOService * from )
4111 {
4112 	assert(from);
4113 	switch (from->fDriverCallReason) {
4114 	case kDriverCallSetPowerState:
4115 		from->driverSetPowerState();
4116 		break;
4117 
4118 	case kDriverCallInformPreChange:
4119 	case kDriverCallInformPostChange:
4120 		from->driverInformPowerChange();
4121 		break;
4122 
4123 	case kRootDomainInformPreChange:
4124 		getPMRootDomain()->willNotifyPowerChildren(from->fHeadNotePowerState);
4125 		break;
4126 
4127 	default:
4128 		panic("IOService::pmDriverCallout bad machine state %x",
4129 		    from->fDriverCallReason);
4130 	}
4131 
4132 	gIOPMWorkLoop->runAction(actionDriverCalloutDone,
4133 	    /* target */ from,
4134 	    /* arg0   */ (void *) from->pwrMgt );
4135 }
4136 
4137 //*********************************************************************************
4138 // [private] driverSetPowerState
4139 //
4140 // Thread call context
4141 //*********************************************************************************
4142 
4143 void
driverSetPowerState(void)4144 IOService::driverSetPowerState( void )
4145 {
4146 	IOPMPowerStateIndex powerState;
4147 	DriverCallParam *   param;
4148 	IOPMDriverCallEntry callEntry;
4149 	AbsoluteTime        end;
4150 	IOReturn            result;
4151 	uint32_t            oldPowerState = getPowerState();
4152 	const OSMetaClass  *controllingDriverMetaClass = NULL;
4153 	uint32_t            controllingDriverRegistryEntryID = 0;
4154 
4155 	assert( fDriverCallBusy );
4156 	assert( fDriverCallParamPtr );
4157 	assert( fDriverCallParamCount == 1 );
4158 
4159 	param = (DriverCallParam *) fDriverCallParamPtr;
4160 	powerState = fHeadNotePowerState;
4161 	if (fControllingDriver) {
4162 		controllingDriverMetaClass = fControllingDriver->getMetaClass();
4163 		controllingDriverRegistryEntryID = (uint32_t)fControllingDriver->getRegistryEntryID();
4164 	}
4165 
4166 	if (assertPMDriverCall(&callEntry, kIOPMDriverCallMethodSetPowerState)) {
4167 		SOCD_TRACE_XNU_START(PM_SET_POWER_STATE,
4168 		    ADDR(controllingDriverMetaClass),
4169 		    ADDR(this->getMetaClass()),
4170 		    PACK_2X32(VALUE(controllingDriverRegistryEntryID), VALUE(this->getRegistryEntryID())),
4171 		    PACK_2X32(VALUE(oldPowerState), VALUE(powerState)));
4172 
4173 		OUR_PMLogFuncStart(kPMLogProgramHardware, (uintptr_t) this, powerState);
4174 		clock_get_uptime(&fDriverCallStartTime);
4175 
4176 		if (reserved && reserved->uvars && reserved->uvars->userServer) {
4177 			result = reserved->uvars->userServer->serviceSetPowerState(fControllingDriver, this, fHeadNotePowerArrayEntry->capabilityFlags, powerState);
4178 		} else {
4179 			result = fControllingDriver->setPowerState( powerState, this );
4180 		}
4181 		clock_get_uptime(&end);
4182 		OUR_PMLogFuncEnd(kPMLogProgramHardware, (uintptr_t) this, (UInt32) result);
4183 		SOCD_TRACE_XNU_END(PM_SET_POWER_STATE,
4184 		    ADDR(controllingDriverMetaClass),
4185 		    ADDR(this->getMetaClass()),
4186 		    PACK_2X32(VALUE(controllingDriverRegistryEntryID), VALUE(this->getRegistryEntryID())),
4187 		    PACK_2X32(VALUE(result), VALUE(powerState)));
4188 
4189 		deassertPMDriverCall(&callEntry);
4190 
4191 		// Record the most recent max power state residency timings.
4192 		// Use with DeviceActiveTimestamp to diagnose tickle issues.
4193 		if (powerState == fHighestPowerState) {
4194 			fMaxPowerStateEntryTime = end;
4195 		} else if (oldPowerState == fHighestPowerState) {
4196 			fMaxPowerStateExitTime = end;
4197 		}
4198 
4199 		if (result < 0) {
4200 			PM_LOG("%s::setPowerState(%p, %lu -> %lu) returned 0x%x\n",
4201 			    fName, OBFUSCATE(this), fCurrentPowerState, powerState, result);
4202 		}
4203 
4204 
4205 		if ((result == IOPMAckImplied) || (result < 0)) {
4206 			uint64_t    nsec;
4207 
4208 			SUB_ABSOLUTETIME(&end, &fDriverCallStartTime);
4209 			absolutetime_to_nanoseconds(end, &nsec);
4210 			if (nsec > gIOPMSetPowerStateLogNS) {
4211 				getPMRootDomain()->pmStatsRecordApplicationResponse(
4212 					gIOPMStatsDriverPSChangeSlow,
4213 					fName, kDriverCallSetPowerState, NS_TO_MS(nsec), getRegistryEntryID(),
4214 					NULL, powerState);
4215 			}
4216 		}
4217 	} else {
4218 		result = kIOPMAckImplied;
4219 	}
4220 
4221 	param->Result = result;
4222 }
4223 
4224 //*********************************************************************************
4225 // [private] driverInformPowerChange
4226 //
4227 // Thread call context
4228 //*********************************************************************************
4229 
4230 void
driverInformPowerChange(void)4231 IOService::driverInformPowerChange( void )
4232 {
4233 	IOPMinformee *      informee;
4234 	IOService *         driver;
4235 	DriverCallParam *   param;
4236 	IOPMDriverCallEntry callEntry;
4237 	IOPMPowerFlags      powerFlags;
4238 	IOPMPowerStateIndex powerState;
4239 	AbsoluteTime        end;
4240 	IOReturn            result;
4241 	IOItemCount         count;
4242 	IOOptionBits        callMethod = (fDriverCallReason == kDriverCallInformPreChange) ?
4243 	    kIOPMDriverCallMethodWillChange : kIOPMDriverCallMethodDidChange;
4244 
4245 	assert( fDriverCallBusy );
4246 	assert( fDriverCallParamPtr );
4247 	assert( fDriverCallParamCount );
4248 
4249 	param = (DriverCallParam *) fDriverCallParamPtr;
4250 	count = fDriverCallParamCount;
4251 
4252 	powerFlags = fHeadNotePowerArrayEntry->capabilityFlags;
4253 	powerState = fHeadNotePowerState;
4254 
4255 	for (IOItemCount i = 0; i < count; i++) {
4256 		informee = (IOPMinformee *) param->Target;
4257 		driver   = informee->whatObject;
4258 
4259 		if (assertPMDriverCall(&callEntry, callMethod, informee)) {
4260 			SOCD_TRACE_XNU_START(PM_INFORM_POWER_CHANGE,
4261 			    ADDR(driver->getMetaClass()),
4262 			    ADDR(this->getMetaClass()),
4263 			    PACK_2X32(VALUE(driver->getRegistryEntryID()), VALUE(this->getRegistryEntryID())),
4264 			    PACK_2X32(VALUE(fDriverCallReason), VALUE(powerState)));
4265 
4266 			if (fDriverCallReason == kDriverCallInformPreChange) {
4267 				OUR_PMLogFuncStart(kPMLogInformDriverPreChange, (uintptr_t) this, powerState);
4268 				clock_get_uptime(&informee->startTime);
4269 				result = driver->powerStateWillChangeTo(powerFlags, powerState, this);
4270 				clock_get_uptime(&end);
4271 				OUR_PMLogFuncEnd(kPMLogInformDriverPreChange, (uintptr_t) this, result);
4272 			} else {
4273 				OUR_PMLogFuncStart(kPMLogInformDriverPostChange, (uintptr_t) this, powerState);
4274 				clock_get_uptime(&informee->startTime);
4275 				result = driver->powerStateDidChangeTo(powerFlags, powerState, this);
4276 				clock_get_uptime(&end);
4277 				OUR_PMLogFuncEnd(kPMLogInformDriverPostChange, (uintptr_t) this, result);
4278 			}
4279 
4280 			SOCD_TRACE_XNU_END(PM_INFORM_POWER_CHANGE,
4281 			    ADDR(driver->getMetaClass()),
4282 			    ADDR(this->getMetaClass()),
4283 			    PACK_2X32(VALUE(driver->getRegistryEntryID()), VALUE(this->getRegistryEntryID())),
4284 			    PACK_2X32(VALUE(fDriverCallReason), VALUE(result)));
4285 
4286 			deassertPMDriverCall(&callEntry);
4287 
4288 
4289 			if ((result == IOPMAckImplied) || (result < 0)) {
4290 				uint64_t nsec;
4291 
4292 				SUB_ABSOLUTETIME(&end, &informee->startTime);
4293 				absolutetime_to_nanoseconds(end, &nsec);
4294 				if (nsec > gIOPMSetPowerStateLogNS) {
4295 					getPMRootDomain()->pmStatsRecordApplicationResponse(
4296 						gIOPMStatsDriverPSChangeSlow, driver->getName(),
4297 						fDriverCallReason, NS_TO_MS(nsec), driver->getRegistryEntryID(),
4298 						NULL, powerState);
4299 				}
4300 			}
4301 		} else {
4302 			result = kIOPMAckImplied;
4303 		}
4304 
4305 		param->Result = result;
4306 		param++;
4307 	}
4308 }
4309 
4310 //*********************************************************************************
4311 // [private] notifyChild
4312 //
4313 // Notify a power domain child of an upcoming power change.
4314 // If the object acknowledges the current change, we return TRUE.
4315 //*********************************************************************************
4316 
4317 bool
notifyChild(IOPowerConnection * theNub)4318 IOService::notifyChild( IOPowerConnection * theNub )
4319 {
4320 	IOReturn                ret = IOPMAckImplied;
4321 	unsigned long           childPower;
4322 	IOService *             theChild;
4323 	IOPMRequest *           childRequest;
4324 	IOPMPowerChangeFlags    requestArg2;
4325 	int                     requestType;
4326 
4327 	PM_ASSERT_IN_GATE();
4328 	theChild = (IOService *)(theNub->copyChildEntry(gIOPowerPlane));
4329 	if (!theChild) {
4330 		return true;
4331 	}
4332 
4333 	// Unless the child handles the notification immediately and returns
4334 	// kIOPMAckImplied, we'll be awaiting their acknowledgement later.
4335 	fHeadNotePendingAcks++;
4336 	theNub->setAwaitingAck(true);
4337 
4338 	requestArg2 = fHeadNoteChangeFlags;
4339 	if (StateOrder(fHeadNotePowerState) < StateOrder(fCurrentPowerState)) {
4340 		requestArg2 |= kIOPMDomainPowerDrop;
4341 	}
4342 
4343 	requestType = fIsPreChange ?
4344 	    kIOPMRequestTypePowerDomainWillChange :
4345 	    kIOPMRequestTypePowerDomainDidChange;
4346 
4347 	childRequest = acquirePMRequest( theChild, requestType );
4348 	if (childRequest) {
4349 		theNub->retain();
4350 		childRequest->fArg0 = (void *) fHeadNotePowerArrayEntry->outputPowerFlags;
4351 		childRequest->fArg1 = (void *) theNub;
4352 		childRequest->fArg2 = (void *)(uintptr_t) requestArg2;
4353 		theChild->submitPMRequest( childRequest );
4354 		ret = IOPMWillAckLater;
4355 	} else {
4356 		ret = IOPMAckImplied;
4357 		fHeadNotePendingAcks--;
4358 		theNub->setAwaitingAck(false);
4359 		childPower = theChild->currentPowerConsumption();
4360 		if (childPower == kIOPMUnknown) {
4361 			fHeadNotePowerArrayEntry->staticPower = kIOPMUnknown;
4362 		} else {
4363 			if (fHeadNotePowerArrayEntry->staticPower != kIOPMUnknown) {
4364 				fHeadNotePowerArrayEntry->staticPower += childPower;
4365 			}
4366 		}
4367 	}
4368 
4369 	theChild->release();
4370 	return IOPMAckImplied == ret;
4371 }
4372 
4373 //*********************************************************************************
4374 // [private] notifyControllingDriver
4375 //*********************************************************************************
4376 
4377 bool
notifyControllingDriver(void)4378 IOService::notifyControllingDriver( void )
4379 {
4380 	DriverCallParam *   param;
4381 
4382 	PM_ASSERT_IN_GATE();
4383 	assert( fDriverCallParamCount == 0  );
4384 	assert( fControllingDriver );
4385 
4386 	if (fInitialSetPowerState) {
4387 		fInitialSetPowerState = false;
4388 		fHeadNoteChangeFlags |= kIOPMInitialPowerChange;
4389 
4390 		// Driver specified flag to skip the inital setPowerState()
4391 		if (fHeadNotePowerArrayEntry->capabilityFlags & kIOPMInitialDeviceState) {
4392 			return false;
4393 		}
4394 	}
4395 
4396 	param = (DriverCallParam *) fDriverCallParamPtr;
4397 	if (!param) {
4398 		param = IONew(DriverCallParam, 1);
4399 		if (!param) {
4400 			return false; // no memory
4401 		}
4402 		fDriverCallParamPtr   = (void *) param;
4403 		fDriverCallParamSlots = 1;
4404 	}
4405 
4406 	param->Target = fControllingDriver;
4407 	fDriverCallParamCount = 1;
4408 	fDriverTimer = -1;
4409 
4410 	// Block state machine and wait for callout completion.
4411 	assert(!fDriverCallBusy);
4412 	fDriverCallBusy = true;
4413 	thread_call_enter( fDriverCallEntry );
4414 
4415 	return true;
4416 }
4417 
4418 //*********************************************************************************
4419 // [private] notifyControllingDriverDone
4420 //*********************************************************************************
4421 
4422 void
notifyControllingDriverDone(void)4423 IOService::notifyControllingDriverDone( void )
4424 {
4425 	DriverCallParam *   param;
4426 	IOReturn            result;
4427 
4428 	PM_ASSERT_IN_GATE();
4429 	param = (DriverCallParam *) fDriverCallParamPtr;
4430 
4431 	assert( fDriverCallBusy == false );
4432 	assert( fMachineState == kIOPM_DriverThreadCallDone );
4433 
4434 	if (param && fDriverCallParamCount) {
4435 		assert(fDriverCallParamCount == 1);
4436 
4437 		// the return value from setPowerState()
4438 		result = param->Result;
4439 
4440 		if ((result == IOPMAckImplied) || (result < 0)) {
4441 			fDriverTimer = 0;
4442 		} else if (fDriverTimer) {
4443 			assert(fDriverTimer == -1);
4444 
4445 			// Driver has not acked, and has returned a positive result.
4446 			// Enforce a minimum permissible timeout value.
4447 			// Make the min value large enough so timeout is less likely
4448 			// to occur if a driver misinterpreted that the return value
4449 			// should be in microsecond units.  And make it large enough
4450 			// to be noticeable if a driver neglects to ack.
4451 
4452 			if (result < kMinAckTimeoutTicks) {
4453 				result = kMinAckTimeoutTicks;
4454 			}
4455 
4456 			fDriverTimer = (result / (ACK_TIMER_PERIOD / ns_per_us)) + 1;
4457 		}
4458 		// else, child has already acked and driver_timer reset to 0.
4459 
4460 		fDriverCallParamCount = 0;
4461 
4462 		if (fDriverTimer) {
4463 			OUR_PMLog(kPMLogStartAckTimer, 0, 0);
4464 			start_ack_timer();
4465 			getPMRootDomain()->reset_watchdog_timer(this, result / USEC_PER_SEC + 1);
4466 		}
4467 	}
4468 
4469 	MS_POP(); // pushed by OurChangeSetPowerState()
4470 	fIsPreChange  = false;
4471 }
4472 
4473 //*********************************************************************************
4474 // [private] all_done
4475 //
4476 // A power change is done.
4477 //*********************************************************************************
4478 
4479 void
all_done(void)4480 IOService::all_done( void )
4481 {
4482 	IOPMPowerStateIndex     prevPowerState;
4483 	const IOPMPSEntry *     powerStatePtr;
4484 	IOPMDriverCallEntry     callEntry;
4485 	uint32_t                prevMachineState = fMachineState;
4486 	bool                    actionCalled = false;
4487 	uint64_t                ts;
4488 
4489 	fMachineState = kIOPM_Finished;
4490 
4491 	if ((fHeadNoteChangeFlags & kIOPMSynchronize) &&
4492 	    ((prevMachineState == kIOPM_Finished) ||
4493 	    (prevMachineState == kIOPM_SyncFinish))) {
4494 		// Sync operation and no power change occurred.
4495 		// Do not inform driver and clients about this request completion,
4496 		// except for the originator (root domain).
4497 
4498 		PM_ACTION_CHANGE(actionPowerChangeDone,
4499 		    fHeadNotePowerState, fHeadNoteChangeFlags);
4500 
4501 		if (getPMRequestType() == kIOPMRequestTypeSynchronizePowerTree) {
4502 			powerChangeDone(fCurrentPowerState);
4503 		} else if (fAdvisoryTickleUsed) {
4504 			// Not root domain and advisory tickle target.
4505 			// Re-adjust power after power tree sync at the 'did' pass
4506 			// to recompute desire and adjust power state between dark
4507 			// and full wake transitions. Root domain is responsible
4508 			// for calling setAdvisoryTickleEnable() before starting
4509 			// the kIOPMSynchronize power change.
4510 
4511 			if (!fAdjustPowerScheduled &&
4512 			    (fHeadNoteChangeFlags & kIOPMDomainDidChange)) {
4513 				IOPMRequest * request;
4514 				request = acquirePMRequest( this, kIOPMRequestTypeAdjustPowerState );
4515 				if (request) {
4516 					submitPMRequest( request );
4517 					fAdjustPowerScheduled = true;
4518 				}
4519 			}
4520 		}
4521 
4522 		return;
4523 	}
4524 
4525 	// our power change
4526 	if (fHeadNoteChangeFlags & kIOPMSelfInitiated) {
4527 		// power state changed
4528 		if ((fHeadNoteChangeFlags & kIOPMNotDone) == 0) {
4529 			trackSystemSleepPreventers(
4530 				fCurrentPowerState, fHeadNotePowerState, fHeadNoteChangeFlags);
4531 
4532 			// we changed, tell our parent
4533 			requestDomainPower(fHeadNotePowerState);
4534 
4535 			// yes, did power raise?
4536 			if (StateOrder(fCurrentPowerState) < StateOrder(fHeadNotePowerState)) {
4537 				// yes, inform clients and apps
4538 				tellChangeUp(fHeadNotePowerState);
4539 			}
4540 			prevPowerState = fCurrentPowerState;
4541 			// either way
4542 			fCurrentPowerState = fHeadNotePowerState;
4543 			PM_LOCK();
4544 			if (fReportBuf) {
4545 				ts = mach_absolute_time();
4546 				STATEREPORT_SETSTATE(fReportBuf, (uint16_t) fCurrentPowerState, ts);
4547 			}
4548 			PM_UNLOCK();
4549 #if PM_VARS_SUPPORT
4550 			fPMVars->myCurrentState = fCurrentPowerState;
4551 #endif
4552 			OUR_PMLog(kPMLogChangeDone, fCurrentPowerState, prevPowerState);
4553 			PM_ACTION_CHANGE(actionPowerChangeDone,
4554 			    prevPowerState, fHeadNoteChangeFlags);
4555 			actionCalled = true;
4556 
4557 			powerStatePtr = &fPowerStates[fCurrentPowerState];
4558 			fCurrentCapabilityFlags = powerStatePtr->capabilityFlags;
4559 			if (fCurrentCapabilityFlags & kIOPMStaticPowerValid) {
4560 				fCurrentPowerConsumption = powerStatePtr->staticPower;
4561 			}
4562 
4563 			if (fHeadNoteChangeFlags & kIOPMRootChangeDown) {
4564 				// Bump tickle generation count once the entire tree is down
4565 				gIOPMTickleGeneration++;
4566 			}
4567 
4568 			// inform subclass policy-maker
4569 			if (fPCDFunctionOverride && fParentsKnowState &&
4570 			    assertPMDriverCall(&callEntry, kIOPMDriverCallMethodChangeDone, NULL, kIOPMDriverCallNoInactiveCheck)) {
4571 				powerChangeDone(prevPowerState);
4572 				deassertPMDriverCall(&callEntry);
4573 			}
4574 		} else if (getPMRequestType() == kIOPMRequestTypeRequestPowerStateOverride) {
4575 			// changePowerStateWithOverrideTo() was cancelled
4576 			fOverrideMaxPowerState = kIOPMPowerStateMax;
4577 		}
4578 	}
4579 
4580 	// parent-initiated power change
4581 	if (fHeadNoteChangeFlags & kIOPMParentInitiated) {
4582 		if (fHeadNoteChangeFlags & kIOPMRootChangeDown) {
4583 			ParentChangeRootChangeDown();
4584 		}
4585 
4586 		// power state changed
4587 		if ((fHeadNoteChangeFlags & kIOPMNotDone) == 0) {
4588 			trackSystemSleepPreventers(
4589 				fCurrentPowerState, fHeadNotePowerState, fHeadNoteChangeFlags);
4590 
4591 			// did power raise?
4592 			if (StateOrder(fCurrentPowerState) < StateOrder(fHeadNotePowerState)) {
4593 				// yes, inform clients and apps
4594 				tellChangeUp(fHeadNotePowerState);
4595 			}
4596 			// either way
4597 			prevPowerState = fCurrentPowerState;
4598 			fCurrentPowerState = fHeadNotePowerState;
4599 			PM_LOCK();
4600 			if (fReportBuf) {
4601 				ts = mach_absolute_time();
4602 				STATEREPORT_SETSTATE(fReportBuf, (uint16_t) fCurrentPowerState, ts);
4603 			}
4604 			PM_UNLOCK();
4605 #if PM_VARS_SUPPORT
4606 			fPMVars->myCurrentState = fCurrentPowerState;
4607 #endif
4608 
4609 			OUR_PMLog(kPMLogChangeDone, fCurrentPowerState, prevPowerState);
4610 			PM_ACTION_CHANGE(actionPowerChangeDone,
4611 			    prevPowerState, fHeadNoteChangeFlags);
4612 			actionCalled = true;
4613 
4614 			powerStatePtr = &fPowerStates[fCurrentPowerState];
4615 			fCurrentCapabilityFlags = powerStatePtr->capabilityFlags;
4616 			if (fCurrentCapabilityFlags & kIOPMStaticPowerValid) {
4617 				fCurrentPowerConsumption = powerStatePtr->staticPower;
4618 			}
4619 
4620 			// inform subclass policy-maker
4621 			if (fPCDFunctionOverride && fParentsKnowState &&
4622 			    assertPMDriverCall(&callEntry, kIOPMDriverCallMethodChangeDone, NULL, kIOPMDriverCallNoInactiveCheck)) {
4623 				powerChangeDone(prevPowerState);
4624 				deassertPMDriverCall(&callEntry);
4625 			}
4626 		}
4627 	}
4628 
4629 	// When power rises enough to satisfy the tickle's desire for more power,
4630 	// the condition preventing idle-timer from dropping power is removed.
4631 
4632 	if (StateOrder(fCurrentPowerState) >= StateOrder(fIdleTimerMinPowerState)) {
4633 		fIdleTimerMinPowerState = kPowerStateZero;
4634 	}
4635 
4636 	if (!actionCalled) {
4637 		PM_ACTION_CHANGE(actionPowerChangeDone,
4638 		    fHeadNotePowerState, fHeadNoteChangeFlags);
4639 	}
4640 }
4641 
4642 // MARK: -
4643 // MARK: Power Change Initiated by Driver
4644 
4645 //*********************************************************************************
4646 // [private] OurChangeStart
4647 //
4648 // Begin the processing of a power change initiated by us.
4649 //*********************************************************************************
4650 
4651 void
OurChangeStart(void)4652 IOService::OurChangeStart( void )
4653 {
4654 	PM_ASSERT_IN_GATE();
4655 	OUR_PMLog( kPMLogStartDeviceChange, fHeadNotePowerState, fCurrentPowerState );
4656 
4657 	// fMaxPowerState is our maximum possible power state based on the current
4658 	// power state of our parents.  If we are trying to raise power beyond the
4659 	// maximum, send an async request for more power to all parents.
4660 
4661 	if (!IS_PM_ROOT && (StateOrder(fMaxPowerState) < StateOrder(fHeadNotePowerState))) {
4662 		fHeadNoteChangeFlags |= kIOPMNotDone;
4663 		requestDomainPower(fHeadNotePowerState);
4664 		OurChangeFinish();
4665 		return;
4666 	}
4667 
4668 	// Redundant power changes skips to the end of the state machine.
4669 
4670 	if (!fInitialPowerChange && (fHeadNotePowerState == fCurrentPowerState)) {
4671 		OurChangeFinish();
4672 		return;
4673 	}
4674 	fInitialPowerChange = false;
4675 
4676 	// Change started, but may not complete...
4677 	// Can be canceled (power drop) or deferred (power rise).
4678 
4679 	PM_ACTION_CHANGE(actionPowerChangeStart, fHeadNotePowerState, &fHeadNoteChangeFlags);
4680 
4681 	// Two separate paths, depending if power is being raised or lowered.
4682 	// Lowering power is subject to approval by clients of this service.
4683 
4684 	if (IS_POWER_DROP) {
4685 		fDoNotPowerDown = false;
4686 
4687 		// Ask for persmission to drop power state
4688 		fMachineState = kIOPM_OurChangeTellClientsPowerDown;
4689 		fOutOfBandParameter = kNotifyApps;
4690 		askChangeDown(fHeadNotePowerState);
4691 	} else {
4692 		// This service is raising power and parents are able to support the
4693 		// new power state. However a parent may have already committed to
4694 		// drop power, which might force this object to temporarily drop power.
4695 		// This results in "oscillations" before the state machines converge
4696 		// to a steady state.
4697 		//
4698 		// To prevent this, a child must make a power reservation against all
4699 		// parents before raising power. If the reservation fails, indicating
4700 		// that the child will be unable to sustain the higher power state,
4701 		// then the child will signal the parent to adjust power, and the child
4702 		// will defer its power change.
4703 
4704 		IOReturn ret;
4705 
4706 		// Reserve parent power necessary to achieve fHeadNotePowerState.
4707 		ret = requestDomainPower( fHeadNotePowerState, kReserveDomainPower );
4708 		if (ret != kIOReturnSuccess) {
4709 			// Reservation failed, defer power rise.
4710 			fHeadNoteChangeFlags |= kIOPMNotDone;
4711 			OurChangeFinish();
4712 			return;
4713 		}
4714 
4715 		OurChangeTellCapabilityWillChange();
4716 	}
4717 }
4718 
4719 //*********************************************************************************
4720 // [private] requestDomainPowerApplier
4721 //
4722 // Call requestPowerDomainState() on all power parents.
4723 //*********************************************************************************
4724 
4725 struct IOPMRequestDomainPowerContext {
4726 	IOService *     child;          // the requesting child
4727 	IOPMPowerFlags  requestPowerFlags;// power flags requested by child
4728 };
4729 
4730 static void
requestDomainPowerApplier(IORegistryEntry * entry,void * inContext)4731 requestDomainPowerApplier(
4732 	IORegistryEntry *   entry,
4733 	void *              inContext )
4734 {
4735 	IOPowerConnection *             connection;
4736 	IOService *                     parent;
4737 	IOPMRequestDomainPowerContext * context;
4738 
4739 	if ((connection = OSDynamicCast(IOPowerConnection, entry)) == NULL) {
4740 		return;
4741 	}
4742 	parent = (IOService *) connection->copyParentEntry(gIOPowerPlane);
4743 	if (!parent) {
4744 		return;
4745 	}
4746 
4747 	assert(inContext);
4748 	context = (IOPMRequestDomainPowerContext *) inContext;
4749 
4750 	if (connection->parentKnowsState() && connection->getReadyFlag()) {
4751 		parent->requestPowerDomainState(
4752 			context->requestPowerFlags,
4753 			connection,
4754 			IOPMLowestState);
4755 	}
4756 
4757 	parent->release();
4758 }
4759 
4760 //*********************************************************************************
4761 // [private] requestDomainPower
4762 //
4763 // Called by a power child to broadcast its desired power state to all parents.
4764 // If the child self-initiates a power change, it must call this function to
4765 // allow its parents to adjust power state.
4766 //*********************************************************************************
4767 
4768 IOReturn
requestDomainPower(IOPMPowerStateIndex ourPowerState,IOOptionBits options)4769 IOService::requestDomainPower(
4770 	IOPMPowerStateIndex ourPowerState,
4771 	IOOptionBits        options )
4772 {
4773 	IOPMPowerFlags                  requestPowerFlags;
4774 	IOPMPowerStateIndex             maxPowerState;
4775 	IOPMRequestDomainPowerContext   context;
4776 
4777 	PM_ASSERT_IN_GATE();
4778 	assert(ourPowerState < fNumberOfPowerStates);
4779 	if (ourPowerState >= fNumberOfPowerStates) {
4780 		return kIOReturnBadArgument;
4781 	}
4782 	if (IS_PM_ROOT) {
4783 		return kIOReturnSuccess;
4784 	}
4785 
4786 	// Fetch our input power flags for the requested power state.
4787 	// Parent request is stated in terms of required power flags.
4788 
4789 	requestPowerFlags = fPowerStates[ourPowerState].inputPowerFlags;
4790 
4791 	// Disregard the "previous request" for power reservation.
4792 
4793 	if (((options & kReserveDomainPower) == 0) &&
4794 	    (fPreviousRequestPowerFlags == requestPowerFlags)) {
4795 		// skip if domain already knows our requirements
4796 		goto done;
4797 	}
4798 	fPreviousRequestPowerFlags = requestPowerFlags;
4799 
4800 	// The results will be collected by fHeadNoteDomainTargetFlags
4801 	context.child              = this;
4802 	context.requestPowerFlags  = requestPowerFlags;
4803 	fHeadNoteDomainTargetFlags = 0;
4804 	applyToParents(requestDomainPowerApplier, &context, gIOPowerPlane);
4805 
4806 	if (options & kReserveDomainPower) {
4807 		maxPowerState = fControllingDriver->maxCapabilityForDomainState(
4808 			fHeadNoteDomainTargetFlags );
4809 
4810 		if (StateOrder(maxPowerState) < StateOrder(ourPowerState)) {
4811 			PM_LOG1("%s: power desired %u:0x%x got %u:0x%x\n",
4812 			    getName(),
4813 			    (uint32_t) ourPowerState, (uint32_t) requestPowerFlags,
4814 			    (uint32_t) maxPowerState, (uint32_t) fHeadNoteDomainTargetFlags);
4815 			return kIOReturnNoPower;
4816 		}
4817 	}
4818 
4819 done:
4820 	return kIOReturnSuccess;
4821 }
4822 
4823 //*********************************************************************************
4824 // [private] OurSyncStart
4825 //*********************************************************************************
4826 
4827 void
OurSyncStart(void)4828 IOService::OurSyncStart( void )
4829 {
4830 	PM_ASSERT_IN_GATE();
4831 
4832 	if (fInitialPowerChange) {
4833 		return;
4834 	}
4835 
4836 	PM_ACTION_CHANGE(actionPowerChangeStart, fHeadNotePowerState, &fHeadNoteChangeFlags);
4837 
4838 	if (fHeadNoteChangeFlags & kIOPMNotDone) {
4839 		OurChangeFinish();
4840 		return;
4841 	}
4842 
4843 	if (fHeadNoteChangeFlags & kIOPMSyncTellPowerDown) {
4844 		fDoNotPowerDown = false;
4845 
4846 		// Ask for permission to drop power state
4847 		fMachineState = kIOPM_SyncTellClientsPowerDown;
4848 		fOutOfBandParameter = kNotifyApps;
4849 		askChangeDown(fHeadNotePowerState);
4850 	} else {
4851 		// Only inform capability app and clients.
4852 		tellSystemCapabilityChange( kIOPM_SyncNotifyWillChange );
4853 	}
4854 }
4855 
4856 //*********************************************************************************
4857 // [private] OurChangeTellClientsPowerDown
4858 //
4859 // All applications and kernel clients have acknowledged our permission to drop
4860 // power. Here we notify them that we will lower the power and wait for acks.
4861 //*********************************************************************************
4862 
4863 void
OurChangeTellClientsPowerDown(void)4864 IOService::OurChangeTellClientsPowerDown( void )
4865 {
4866 	if (!IS_ROOT_DOMAIN) {
4867 		fMachineState = kIOPM_OurChangeTellPriorityClientsPowerDown;
4868 	} else {
4869 		fMachineState = kIOPM_OurChangeTellUserPMPolicyPowerDown;
4870 	}
4871 	tellChangeDown1(fHeadNotePowerState);
4872 }
4873 
4874 //*********************************************************************************
4875 // [private] OurChangeTellUserPMPolicyPowerDown
4876 //
4877 // All applications and kernel clients have acknowledged our permission to drop
4878 // power. Here we notify power management policy in user-space and wait for acks
4879 // one last time before we lower power
4880 //*********************************************************************************
4881 void
OurChangeTellUserPMPolicyPowerDown(void)4882 IOService::OurChangeTellUserPMPolicyPowerDown( void )
4883 {
4884 	fMachineState = kIOPM_OurChangeTellPriorityClientsPowerDown;
4885 	fOutOfBandParameter = kNotifyApps;
4886 
4887 	tellClientsWithResponse(kIOPMMessageLastCallBeforeSleep);
4888 }
4889 
4890 //*********************************************************************************
4891 // [private] OurChangeTellPriorityClientsPowerDown
4892 //
4893 // All applications and kernel clients have acknowledged our intention to drop
4894 // power.  Here we notify "priority" clients that we are lowering power.
4895 //*********************************************************************************
4896 
4897 void
OurChangeTellPriorityClientsPowerDown(void)4898 IOService::OurChangeTellPriorityClientsPowerDown( void )
4899 {
4900 	fMachineState = kIOPM_OurChangeNotifyInterestedDriversWillChange;
4901 	tellChangeDown2(fHeadNotePowerState);
4902 }
4903 
4904 //*********************************************************************************
4905 // [private] OurChangeTellCapabilityWillChange
4906 //
4907 // Extra stage for root domain to notify apps and drivers about the
4908 // system capability change when raising power state.
4909 //*********************************************************************************
4910 
4911 void
OurChangeTellCapabilityWillChange(void)4912 IOService::OurChangeTellCapabilityWillChange( void )
4913 {
4914 	if (!IS_ROOT_DOMAIN) {
4915 		return OurChangeNotifyInterestedDriversWillChange();
4916 	}
4917 
4918 	tellSystemCapabilityChange( kIOPM_OurChangeNotifyInterestedDriversWillChange );
4919 }
4920 
4921 //*********************************************************************************
4922 // [private] OurChangeNotifyInterestedDriversWillChange
4923 //
4924 // All applications and kernel clients have acknowledged our power state change.
4925 // Here we notify interested drivers pre-change.
4926 //*********************************************************************************
4927 
4928 void
OurChangeNotifyInterestedDriversWillChange(void)4929 IOService::OurChangeNotifyInterestedDriversWillChange( void )
4930 {
4931 	IOPMrootDomain * rootDomain;
4932 	if ((rootDomain = getPMRootDomain()) == this) {
4933 		if (IS_POWER_DROP) {
4934 			rootDomain->tracePoint( kIOPMTracePointSleepWillChangeInterests );
4935 		} else {
4936 			rootDomain->tracePoint( kIOPMTracePointWakeWillChangeInterests );
4937 		}
4938 	}
4939 
4940 	notifyAll( kIOPM_OurChangeSetPowerState );
4941 }
4942 
4943 //*********************************************************************************
4944 // [private] OurChangeSetPowerState
4945 //
4946 // Instruct our controlling driver to program the hardware for the power state
4947 // change. Wait for async completions.
4948 //*********************************************************************************
4949 
4950 void
OurChangeSetPowerState(void)4951 IOService::OurChangeSetPowerState( void )
4952 {
4953 	MS_PUSH( kIOPM_OurChangeWaitForPowerSettle );
4954 	fMachineState     = kIOPM_DriverThreadCallDone;
4955 	fDriverCallReason = kDriverCallSetPowerState;
4956 
4957 	if (notifyControllingDriver() == false) {
4958 		notifyControllingDriverDone();
4959 	}
4960 }
4961 
4962 //*********************************************************************************
4963 // [private] OurChangeWaitForPowerSettle
4964 //
4965 // Our controlling driver has completed the power state change we initiated.
4966 // Wait for the driver specified settle time to expire.
4967 //*********************************************************************************
4968 
4969 void
OurChangeWaitForPowerSettle(void)4970 IOService::OurChangeWaitForPowerSettle( void )
4971 {
4972 	fMachineState = kIOPM_OurChangeNotifyInterestedDriversDidChange;
4973 	startSettleTimer();
4974 }
4975 
4976 //*********************************************************************************
4977 // [private] OurChangeNotifyInterestedDriversDidChange
4978 //
4979 // Power has settled on a power change we initiated. Here we notify
4980 // all our interested drivers post-change.
4981 //*********************************************************************************
4982 
4983 void
OurChangeNotifyInterestedDriversDidChange(void)4984 IOService::OurChangeNotifyInterestedDriversDidChange( void )
4985 {
4986 	IOPMrootDomain * rootDomain;
4987 	if ((rootDomain = getPMRootDomain()) == this) {
4988 		rootDomain->tracePoint( IS_POWER_DROP ?
4989 		    kIOPMTracePointSleepDidChangeInterests :
4990 		    kIOPMTracePointWakeDidChangeInterests  );
4991 	}
4992 
4993 	notifyAll( kIOPM_OurChangeTellCapabilityDidChange );
4994 }
4995 
4996 //*********************************************************************************
4997 // [private] OurChangeTellCapabilityDidChange
4998 //
4999 // For root domain to notify capability power-change.
5000 //*********************************************************************************
5001 
5002 void
OurChangeTellCapabilityDidChange(void)5003 IOService::OurChangeTellCapabilityDidChange( void )
5004 {
5005 	if (!IS_ROOT_DOMAIN) {
5006 		return OurChangeFinish();
5007 	}
5008 
5009 	if (!IS_POWER_DROP) {
5010 		// Notify root domain immediately after notifying interested
5011 		// drivers and power children.
5012 		getPMRootDomain()->willTellSystemCapabilityDidChange();
5013 	}
5014 
5015 	getPMRootDomain()->tracePoint( IS_POWER_DROP ?
5016 	    kIOPMTracePointSleepCapabilityClients :
5017 	    kIOPMTracePointWakeCapabilityClients  );
5018 
5019 	tellSystemCapabilityChange( kIOPM_OurChangeFinish );
5020 }
5021 
5022 //*********************************************************************************
5023 // [private] OurChangeFinish
5024 //
5025 // Done with this self-induced power state change.
5026 //*********************************************************************************
5027 
5028 void
OurChangeFinish(void)5029 IOService::OurChangeFinish( void )
5030 {
5031 	all_done();
5032 }
5033 
5034 // MARK: -
5035 // MARK: Power Change Initiated by Parent
5036 
5037 //*********************************************************************************
5038 // [private] ParentChangeStart
5039 //
5040 // Here we begin the processing of a power change initiated by our parent.
5041 //*********************************************************************************
5042 
5043 IOReturn
ParentChangeStart(void)5044 IOService::ParentChangeStart( void )
5045 {
5046 	PM_ASSERT_IN_GATE();
5047 	OUR_PMLog( kPMLogStartParentChange, fHeadNotePowerState, fCurrentPowerState );
5048 
5049 	// Root power domain has transitioned to its max power state
5050 	if ((fHeadNoteChangeFlags & (kIOPMDomainDidChange | kIOPMRootChangeUp)) ==
5051 	    (kIOPMDomainDidChange | kIOPMRootChangeUp)) {
5052 		// Restart the idle timer stopped by ParentChangeRootChangeDown()
5053 		if (fIdleTimerPeriod && fIdleTimerStopped) {
5054 			restartIdleTimer();
5055 		}
5056 	}
5057 
5058 	// Power domain is forcing us to lower power
5059 	if (StateOrder(fHeadNotePowerState) < StateOrder(fCurrentPowerState)) {
5060 		PM_ACTION_CHANGE(actionPowerChangeStart, fHeadNotePowerState, &fHeadNoteChangeFlags);
5061 
5062 		// Tell apps and kernel clients
5063 		fInitialPowerChange = false;
5064 		fMachineState = kIOPM_ParentChangeTellPriorityClientsPowerDown;
5065 		tellChangeDown1(fHeadNotePowerState);
5066 		return IOPMWillAckLater;
5067 	}
5068 
5069 	// Power domain is allowing us to raise power up to fHeadNotePowerState
5070 	if (StateOrder(fHeadNotePowerState) > StateOrder(fCurrentPowerState)) {
5071 		if (StateOrder(fDesiredPowerState) > StateOrder(fCurrentPowerState)) {
5072 			if (StateOrder(fDesiredPowerState) < StateOrder(fHeadNotePowerState)) {
5073 				// We power up, but not all the way
5074 				fHeadNotePowerState = fDesiredPowerState;
5075 				fHeadNotePowerArrayEntry = &fPowerStates[fDesiredPowerState];
5076 				OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
5077 			}
5078 		} else {
5079 			// We don't need to change
5080 			fHeadNotePowerState = fCurrentPowerState;
5081 			fHeadNotePowerArrayEntry = &fPowerStates[fCurrentPowerState];
5082 			OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
5083 		}
5084 	}
5085 
5086 	if (fHeadNoteChangeFlags & kIOPMDomainDidChange) {
5087 		if (StateOrder(fHeadNotePowerState) > StateOrder(fCurrentPowerState)) {
5088 			PM_ACTION_CHANGE(actionPowerChangeStart,
5089 			    fHeadNotePowerState, &fHeadNoteChangeFlags);
5090 
5091 			// Parent did change up - start our change up
5092 			fInitialPowerChange = false;
5093 			ParentChangeTellCapabilityWillChange();
5094 			return IOPMWillAckLater;
5095 		} else if (fHeadNoteChangeFlags & kIOPMRootBroadcastFlags) {
5096 			// No need to change power state, but broadcast change
5097 			// to our children.
5098 			fMachineState     = kIOPM_SyncNotifyDidChange;
5099 			fDriverCallReason = kDriverCallInformPreChange;
5100 			fHeadNoteChangeFlags |= kIOPMNotDone;
5101 			notifyChildren();
5102 			return IOPMWillAckLater;
5103 		}
5104 	}
5105 
5106 	// No power state change necessary
5107 	fHeadNoteChangeFlags |= kIOPMNotDone;
5108 
5109 	all_done();
5110 	return IOPMAckImplied;
5111 }
5112 
5113 //******************************************************************************
5114 // [private] ParentChangeRootChangeDown
5115 //
5116 // Root domain has finished the transition to the system sleep state. And all
5117 // drivers in the power plane should have powered down. Cancel the idle timer,
5118 // and also reset the device desire for those drivers that don't want power
5119 // automatically restored on wake.
5120 //******************************************************************************
5121 
5122 void
ParentChangeRootChangeDown(void)5123 IOService::ParentChangeRootChangeDown( void )
5124 {
5125 	// Always stop the idle timer before root power down
5126 	if (fIdleTimerPeriod && !fIdleTimerStopped) {
5127 		fIdleTimerStopped = true;
5128 		if (fIdleTimer && thread_call_cancel(fIdleTimer)) {
5129 			release();
5130 		}
5131 	}
5132 
5133 	if (fResetPowerStateOnWake) {
5134 		// Reset device desire down to the lowest power state.
5135 		// Advisory tickle desire is intentionally untouched since
5136 		// it has no effect until system is promoted to full wake.
5137 
5138 		if (fDeviceDesire != kPowerStateZero) {
5139 			updatePowerClient(gIOPMPowerClientDevice, kPowerStateZero);
5140 			computeDesiredState(kPowerStateZero, true);
5141 			requestDomainPower( fDesiredPowerState );
5142 			PM_LOG1("%s: tickle desire removed\n", fName);
5143 		}
5144 
5145 		// Invalidate tickle cache so the next tickle will issue a request
5146 		IOLockLock(fActivityLock);
5147 		fDeviceWasActive = false;
5148 		fActivityTicklePowerState = kInvalidTicklePowerState;
5149 		IOLockUnlock(fActivityLock);
5150 
5151 		fIdleTimerMinPowerState = kPowerStateZero;
5152 	} else if (fAdvisoryTickleUsed) {
5153 		// Less aggressive mechanism to accelerate idle timer expiration
5154 		// before system sleep. May not always allow the driver to wake
5155 		// up from system sleep in the min power state.
5156 
5157 		AbsoluteTime    now;
5158 		uint64_t        nsec;
5159 		bool            dropTickleDesire = false;
5160 
5161 		if (fIdleTimerPeriod && !fIdleTimerIgnored &&
5162 		    (fIdleTimerMinPowerState == kPowerStateZero) &&
5163 		    (fDeviceDesire != kPowerStateZero)) {
5164 			IOLockLock(fActivityLock);
5165 
5166 			if (!fDeviceWasActive) {
5167 				// No tickles since the last idle timer expiration.
5168 				// Safe to drop the device desire to zero.
5169 				dropTickleDesire = true;
5170 			} else {
5171 				// Was tickled since the last idle timer expiration,
5172 				// but not in the last minute.
5173 				clock_get_uptime(&now);
5174 				SUB_ABSOLUTETIME(&now, &fDeviceActiveTimestamp);
5175 				absolutetime_to_nanoseconds(now, &nsec);
5176 				if (nsec >= kNoTickleCancelWindow) {
5177 					dropTickleDesire = true;
5178 				}
5179 			}
5180 
5181 			if (dropTickleDesire) {
5182 				// Force the next tickle to raise power state
5183 				fDeviceWasActive = false;
5184 				fActivityTicklePowerState = kInvalidTicklePowerState;
5185 			}
5186 
5187 			IOLockUnlock(fActivityLock);
5188 		}
5189 
5190 		if (dropTickleDesire) {
5191 			// Advisory tickle desire is intentionally untouched since
5192 			// it has no effect until system is promoted to full wake.
5193 
5194 			updatePowerClient(gIOPMPowerClientDevice, kPowerStateZero);
5195 			computeDesiredState(kPowerStateZero, true);
5196 			PM_LOG1("%s: tickle desire dropped\n", fName);
5197 		}
5198 	}
5199 }
5200 
5201 //*********************************************************************************
5202 // [private] ParentChangeTellPriorityClientsPowerDown
5203 //
5204 // All applications and kernel clients have acknowledged our intention to drop
5205 // power.  Here we notify "priority" clients that we are lowering power.
5206 //*********************************************************************************
5207 
5208 void
ParentChangeTellPriorityClientsPowerDown(void)5209 IOService::ParentChangeTellPriorityClientsPowerDown( void )
5210 {
5211 	fMachineState = kIOPM_ParentChangeNotifyInterestedDriversWillChange;
5212 	tellChangeDown2(fHeadNotePowerState);
5213 }
5214 
5215 //*********************************************************************************
5216 // [private] ParentChangeTellCapabilityWillChange
5217 //
5218 // All (legacy) applications and kernel clients have acknowledged, extra stage for
5219 // root domain to notify apps and drivers about the system capability change.
5220 //*********************************************************************************
5221 
5222 void
ParentChangeTellCapabilityWillChange(void)5223 IOService::ParentChangeTellCapabilityWillChange( void )
5224 {
5225 	if (!IS_ROOT_DOMAIN) {
5226 		return ParentChangeNotifyInterestedDriversWillChange();
5227 	}
5228 
5229 	tellSystemCapabilityChange( kIOPM_ParentChangeNotifyInterestedDriversWillChange );
5230 }
5231 
5232 //*********************************************************************************
5233 // [private] ParentChangeNotifyInterestedDriversWillChange
5234 //
5235 // All applications and kernel clients have acknowledged our power state change.
5236 // Here we notify interested drivers pre-change.
5237 //*********************************************************************************
5238 
5239 void
ParentChangeNotifyInterestedDriversWillChange(void)5240 IOService::ParentChangeNotifyInterestedDriversWillChange( void )
5241 {
5242 	notifyAll( kIOPM_ParentChangeSetPowerState );
5243 }
5244 
5245 //*********************************************************************************
5246 // [private] ParentChangeSetPowerState
5247 //
5248 // Instruct our controlling driver to program the hardware for the power state
5249 // change. Wait for async completions.
5250 //*********************************************************************************
5251 
5252 void
ParentChangeSetPowerState(void)5253 IOService::ParentChangeSetPowerState( void )
5254 {
5255 	MS_PUSH( kIOPM_ParentChangeWaitForPowerSettle );
5256 	fMachineState     = kIOPM_DriverThreadCallDone;
5257 	fDriverCallReason = kDriverCallSetPowerState;
5258 
5259 	if (notifyControllingDriver() == false) {
5260 		notifyControllingDriverDone();
5261 	}
5262 }
5263 
5264 //*********************************************************************************
5265 // [private] ParentChangeWaitForPowerSettle
5266 //
5267 // Our controlling driver has completed the power state change initiated by our
5268 // parent. Wait for the driver specified settle time to expire.
5269 //*********************************************************************************
5270 
5271 void
ParentChangeWaitForPowerSettle(void)5272 IOService::ParentChangeWaitForPowerSettle( void )
5273 {
5274 	fMachineState = kIOPM_ParentChangeNotifyInterestedDriversDidChange;
5275 	startSettleTimer();
5276 }
5277 
5278 //*********************************************************************************
5279 // [private] ParentChangeNotifyInterestedDriversDidChange
5280 //
5281 // Power has settled on a power change initiated by our parent. Here we notify
5282 // all our interested drivers post-change.
5283 //*********************************************************************************
5284 
5285 void
ParentChangeNotifyInterestedDriversDidChange(void)5286 IOService::ParentChangeNotifyInterestedDriversDidChange( void )
5287 {
5288 	notifyAll( kIOPM_ParentChangeTellCapabilityDidChange );
5289 }
5290 
5291 //*********************************************************************************
5292 // [private] ParentChangeTellCapabilityDidChange
5293 //
5294 // For root domain to notify capability power-change.
5295 //*********************************************************************************
5296 
5297 void
ParentChangeTellCapabilityDidChange(void)5298 IOService::ParentChangeTellCapabilityDidChange( void )
5299 {
5300 	if (!IS_ROOT_DOMAIN) {
5301 		return ParentChangeAcknowledgePowerChange();
5302 	}
5303 
5304 	tellSystemCapabilityChange( kIOPM_ParentChangeAcknowledgePowerChange );
5305 }
5306 
5307 //*********************************************************************************
5308 // [private] ParentAcknowledgePowerChange
5309 //
5310 // Acknowledge our power parent that our power change is done.
5311 //*********************************************************************************
5312 
5313 void
ParentChangeAcknowledgePowerChange(void)5314 IOService::ParentChangeAcknowledgePowerChange( void )
5315 {
5316 	IORegistryEntry *   nub;
5317 	IOService *         parent;
5318 
5319 	nub = fHeadNoteParentConnection;
5320 	nub->retain();
5321 	all_done();
5322 	parent = (IOService *)nub->copyParentEntry(gIOPowerPlane);
5323 	if (parent) {
5324 		parent->acknowledgePowerChange((IOService *)nub);
5325 		parent->release();
5326 	}
5327 	nub->release();
5328 }
5329 
5330 // MARK: -
5331 // MARK: Ack and Settle timers
5332 
5333 //*********************************************************************************
5334 // [private] settleTimerExpired
5335 //
5336 // Power has settled after our last change.  Notify interested parties that
5337 // there is a new power state.
5338 //*********************************************************************************
5339 
5340 void
settleTimerExpired(void)5341 IOService::settleTimerExpired( void )
5342 {
5343 #if USE_SETTLE_TIMER
5344 	fSettleTimeUS = 0;
5345 	gIOPMWorkQueue->signalWorkAvailable();
5346 #endif
5347 }
5348 
5349 //*********************************************************************************
5350 // settle_timer_expired
5351 //
5352 // Holds a retain while the settle timer callout is in flight.
5353 //*********************************************************************************
5354 
5355 #if USE_SETTLE_TIMER
5356 static void
settle_timer_expired(thread_call_param_t arg0,thread_call_param_t arg1)5357 settle_timer_expired( thread_call_param_t arg0, thread_call_param_t arg1 )
5358 {
5359 	IOService * me = (IOService *) arg0;
5360 
5361 	if (gIOPMWorkLoop && gIOPMWorkQueue) {
5362 		gIOPMWorkLoop->runAction(
5363 			OSMemberFunctionCast(IOWorkLoop::Action, me, &IOService::settleTimerExpired),
5364 			me);
5365 	}
5366 	me->release();
5367 }
5368 #endif
5369 
5370 //*********************************************************************************
5371 // [private] startSettleTimer
5372 //
5373 // Calculate a power-settling delay in microseconds and start a timer.
5374 //*********************************************************************************
5375 
5376 void
startSettleTimer(void)5377 IOService::startSettleTimer( void )
5378 {
5379 #if USE_SETTLE_TIMER
5380 	// This function is broken and serves no useful purpose since it never
5381 	// updates fSettleTimeUS to a non-zero value to stall the state machine,
5382 	// yet it starts a delay timer. It appears no driver relies on a delay
5383 	// from settleUpTime and settleDownTime in the power state table.
5384 
5385 	AbsoluteTime        deadline;
5386 	IOPMPowerStateIndex stateIndex;
5387 	IOPMPowerStateIndex currentOrder, newOrder, i;
5388 	uint32_t            settleTime = 0;
5389 	boolean_t           pending;
5390 
5391 	PM_ASSERT_IN_GATE();
5392 
5393 	currentOrder = StateOrder(fCurrentPowerState);
5394 	newOrder     = StateOrder(fHeadNotePowerState);
5395 
5396 	i = currentOrder;
5397 
5398 	// lowering power
5399 	if (newOrder < currentOrder) {
5400 		while (i > newOrder) {
5401 			stateIndex = fPowerStates[i].stateOrderToIndex;
5402 			settleTime += (uint32_t) fPowerStates[stateIndex].settleDownTime;
5403 			i--;
5404 		}
5405 	}
5406 
5407 	// raising power
5408 	if (newOrder > currentOrder) {
5409 		while (i < newOrder) {
5410 			stateIndex = fPowerStates[i + 1].stateOrderToIndex;
5411 			settleTime += (uint32_t) fPowerStates[stateIndex].settleUpTime;
5412 			i++;
5413 		}
5414 	}
5415 
5416 	if (settleTime) {
5417 		retain();
5418 		clock_interval_to_deadline(settleTime, kMicrosecondScale, &deadline);
5419 		pending = thread_call_enter_delayed(fSettleTimer, deadline);
5420 		if (pending) {
5421 			release();
5422 		}
5423 	}
5424 #endif
5425 }
5426 
5427 //*********************************************************************************
5428 // [private] ackTimerTick
5429 //
5430 // The acknowledgement timeout periodic timer has ticked.
5431 // If we are awaiting acks for a power change notification,
5432 // we decrement the timer word of each interested driver which hasn't acked.
5433 // If a timer word becomes zero, we pretend the driver aknowledged.
5434 // If we are waiting for the controlling driver to change the power
5435 // state of the hardware, we decrement its timer word, and if it becomes
5436 // zero, we pretend the driver acknowledged.
5437 //
5438 // Returns true if the timer tick made it possible to advance to the next
5439 // machine state, false otherwise.
5440 //*********************************************************************************
5441 
5442 #ifndef __LP64__
5443 #if MACH_ASSERT
5444 __dead2
5445 #endif
5446 void
ack_timer_ticked(void)5447 IOService::ack_timer_ticked( void )
5448 {
5449 	assert(false);
5450 }
5451 #endif /* !__LP64__ */
5452 
5453 bool
ackTimerTick(void)5454 IOService::ackTimerTick( void )
5455 {
5456 	IOPMinformee *      nextObject;
5457 	bool                done = false;
5458 
5459 	PM_ASSERT_IN_GATE();
5460 	switch (fMachineState) {
5461 	case kIOPM_OurChangeWaitForPowerSettle:
5462 	case kIOPM_ParentChangeWaitForPowerSettle:
5463 		// are we waiting for controlling driver to acknowledge?
5464 		if (fDriverTimer > 0) {
5465 			// yes, decrement timer tick
5466 			fDriverTimer--;
5467 			if (fDriverTimer == 0) {
5468 				// controlling driver is tardy
5469 				uint64_t nsec = computeTimeDeltaNS(&fDriverCallStartTime);
5470 				OUR_PMLog(kPMLogCtrlDriverTardy, 0, 0);
5471 				setProperty(kIOPMTardyAckSPSKey, kOSBooleanTrue);
5472 				PM_ERROR("%s::setPowerState(%p, %lu -> %lu) timed out after %d ms\n",
5473 				    fName, OBFUSCATE(this), fCurrentPowerState, fHeadNotePowerState, NS_TO_MS(nsec));
5474 
5475 #if DEBUG || DEVELOPMENT || !defined(XNU_TARGET_OS_OSX)
5476 				bool panic_allowed = false;
5477 				uint32_t setpowerstate_panic = -1;
5478 				PE_parse_boot_argn("setpowerstate_panic", &setpowerstate_panic, sizeof(setpowerstate_panic));
5479 				panic_allowed = setpowerstate_panic != 0;
5480 #ifdef CONFIG_XNUPOST
5481 				uint64_t kernel_post_args = 0;
5482 				PE_parse_boot_argn("kernPOST", &kernel_post_args, sizeof(kernel_post_args));
5483 				if (kernel_post_args != 0) {
5484 					panic_allowed = false;
5485 				}
5486 #endif /* CONFIG_XNUPOST */
5487 				if (panic_allowed) {
5488 					// rdar://problem/48743340 - excluding AppleSEPManager from panic
5489 					const char *allowlist = "AppleSEPManager";
5490 					if (strncmp(fName, allowlist, strlen(allowlist))) {
5491 						panic("%s::setPowerState(%p, %lu -> %lu) timed out after %d ms",
5492 						    fName, this, fCurrentPowerState, fHeadNotePowerState, NS_TO_MS(nsec));
5493 					}
5494 				} else {
5495 #ifdef CONFIG_XNUPOST
5496 					if (kernel_post_args != 0) {
5497 						PM_ERROR("setPowerState panic disabled by kernPOST boot-arg\n");
5498 					}
5499 #endif /* CONFIG_XNUPOST */
5500 					if (setpowerstate_panic != 0) {
5501 						PM_ERROR("setPowerState panic disabled by setpowerstate_panic boot-arg\n");
5502 					}
5503 				}
5504 #else /* !(DEBUG || DEVELOPMENT || !defined(XNU_TARGET_OS_OSX)) */
5505 				if (gIOKitDebug & kIOLogDebugPower) {
5506 					panic("%s::setPowerState(%p, %lu -> %lu) timed out after %d ms",
5507 					    fName, this, fCurrentPowerState, fHeadNotePowerState, NS_TO_MS(nsec));
5508 				} else {
5509 					// panic for first party kexts
5510 					const void *function_addr = NULL;
5511 					OSKext *kext = NULL;
5512 					function_addr = OSMemberFunctionCast(const void *, fControllingDriver, &IOService::setPowerState);
5513 					kext = OSKext::lookupKextWithAddress((vm_address_t)function_addr);
5514 					if (kext) {
5515 #if __has_feature(ptrauth_calls)
5516 						function_addr = (const void*)VM_KERNEL_STRIP_PTR(function_addr);
5517 #endif /* __has_feature(ptrauth_calls) */
5518 						const char *bundleID = kext->getIdentifierCString();
5519 						const char *apple_prefix = "com.apple";
5520 						const char *kernel_prefix = "__kernel__";
5521 						if (strncmp(bundleID, apple_prefix, strlen(apple_prefix)) == 0 || strncmp(bundleID, kernel_prefix, strlen(kernel_prefix)) == 0) {
5522 							// first party client
5523 							panic("%s::setPowerState(%p : %p, %lu -> %lu) timed out after %d ms",
5524 							    fName, this, function_addr, fCurrentPowerState, fHeadNotePowerState, NS_TO_MS(nsec));
5525 						}
5526 						kext->release();
5527 					}
5528 				}
5529 #endif /* !(DEBUG || DEVELOPMENT || !defined(XNU_TARGET_OS_OSX)) */
5530 				// Unblock state machine and pretend driver has acked.
5531 				done = true;
5532 				getPMRootDomain()->reset_watchdog_timer(this, 0);
5533 			} else {
5534 				// still waiting, set timer again
5535 				start_ack_timer();
5536 			}
5537 		}
5538 		break;
5539 
5540 	case kIOPM_NotifyChildrenStart:
5541 		// are we waiting for interested parties to acknowledge?
5542 		if (fHeadNotePendingAcks != 0) {
5543 			// yes, go through the list of interested drivers
5544 			nextObject = fInterestedDrivers->firstInList();
5545 			// and check each one
5546 			while (nextObject != NULL) {
5547 				if (nextObject->timer > 0) {
5548 					nextObject->timer--;
5549 					// this one should have acked by now
5550 					if (nextObject->timer == 0) {
5551 						uint64_t nsec = computeTimeDeltaNS(&nextObject->startTime);
5552 						OUR_PMLog(kPMLogIntDriverTardy, 0, 0);
5553 						nextObject->whatObject->setProperty(kIOPMTardyAckPSCKey, kOSBooleanTrue);
5554 						PM_ERROR("%s::powerState%sChangeTo(%p, %s, %lu -> %lu) timed out after %d ms\n",
5555 						    nextObject->whatObject->getName(),
5556 						    (fDriverCallReason == kDriverCallInformPreChange) ? "Will" : "Did",
5557 						    OBFUSCATE(nextObject->whatObject), fName, fCurrentPowerState, fHeadNotePowerState,
5558 						    NS_TO_MS(nsec));
5559 
5560 						// Pretend driver has acked.
5561 						fHeadNotePendingAcks--;
5562 					}
5563 				}
5564 				nextObject = fInterestedDrivers->nextInList(nextObject);
5565 			}
5566 
5567 			// is that the last?
5568 			if (fHeadNotePendingAcks == 0) {
5569 				// yes, we can continue
5570 				done = true;
5571 				getPMRootDomain()->reset_watchdog_timer(this, 0);
5572 			} else {
5573 				// no, set timer again
5574 				start_ack_timer();
5575 			}
5576 		}
5577 		break;
5578 
5579 	// TODO: aggreggate this
5580 	case kIOPM_OurChangeTellClientsPowerDown:
5581 	case kIOPM_OurChangeTellUserPMPolicyPowerDown:
5582 	case kIOPM_OurChangeTellPriorityClientsPowerDown:
5583 	case kIOPM_OurChangeNotifyInterestedDriversWillChange:
5584 	case kIOPM_ParentChangeTellPriorityClientsPowerDown:
5585 	case kIOPM_ParentChangeNotifyInterestedDriversWillChange:
5586 	case kIOPM_SyncTellClientsPowerDown:
5587 	case kIOPM_SyncTellPriorityClientsPowerDown:
5588 	case kIOPM_SyncNotifyWillChange:
5589 	case kIOPM_TellCapabilityChangeDone:
5590 		// apps didn't respond in time
5591 		cleanClientResponses(true);
5592 		OUR_PMLog(kPMLogClientTardy, 0, 1);
5593 		// tardy equates to approval
5594 		done = true;
5595 		break;
5596 
5597 	default:
5598 		PM_LOG1("%s: unexpected ack timer tick (state = %d)\n",
5599 		    getName(), fMachineState);
5600 		break;
5601 	}
5602 	return done;
5603 }
5604 
5605 //*********************************************************************************
5606 // [private] start_watchdog_timer
5607 //*********************************************************************************
5608 void
start_watchdog_timer(void)5609 IOService::start_watchdog_timer( void )
5610 {
5611 	int             timeout;
5612 	uint64_t        deadline;
5613 
5614 	if (!fWatchdogTimer || (kIOSleepWakeWdogOff & gIOKitDebug)) {
5615 		return;
5616 	}
5617 
5618 	IOLockLock(fWatchdogLock);
5619 
5620 	timeout = getPMRootDomain()->getWatchdogTimeout();
5621 	clock_interval_to_deadline(timeout, kSecondScale, &deadline);
5622 	start_watchdog_timer(deadline);
5623 	IOLockUnlock(fWatchdogLock);
5624 }
5625 
5626 void
start_watchdog_timer(uint64_t deadline)5627 IOService::start_watchdog_timer(uint64_t deadline)
5628 {
5629 	IOLockAssert(fWatchdogLock, kIOLockAssertOwned);
5630 	fWatchdogDeadline = deadline;
5631 
5632 	if (!thread_call_isactive(fWatchdogTimer)) {
5633 		thread_call_enter_delayed(fWatchdogTimer, deadline);
5634 	}
5635 }
5636 
5637 //*********************************************************************************
5638 // [private] stop_watchdog_timer
5639 //*********************************************************************************
5640 
5641 void
stop_watchdog_timer(void)5642 IOService::stop_watchdog_timer( void )
5643 {
5644 	if (!fWatchdogTimer || (kIOSleepWakeWdogOff & gIOKitDebug)) {
5645 		return;
5646 	}
5647 
5648 	IOLockLock(fWatchdogLock);
5649 
5650 	thread_call_cancel(fWatchdogTimer);
5651 	fWatchdogDeadline = 0;
5652 
5653 	while (fBlockedArray->getCount()) {
5654 		IOService *obj = OSDynamicCast(IOService, fBlockedArray->getObject(0));
5655 		if (obj) {
5656 			PM_ERROR("WDOG:Object %s unexpected in blocked array\n", obj->fName);
5657 			fBlockedArray->removeObject(0);
5658 		}
5659 	}
5660 
5661 	IOLockUnlock(fWatchdogLock);
5662 }
5663 
5664 //*********************************************************************************
5665 // reset_watchdog_timer
5666 //*********************************************************************************
5667 
5668 void
reset_watchdog_timer(IOService * blockedObject,int pendingResponseTimeout)5669 IOService::reset_watchdog_timer(IOService *blockedObject, int pendingResponseTimeout)
5670 {
5671 	unsigned int i;
5672 	uint64_t    deadline;
5673 	IOService *obj;
5674 
5675 	if (!fWatchdogTimer || (kIOSleepWakeWdogOff & gIOKitDebug)) {
5676 		return;
5677 	}
5678 
5679 
5680 	IOLockLock(fWatchdogLock);
5681 	if (!fWatchdogDeadline) {
5682 		goto exit;
5683 	}
5684 
5685 	i = fBlockedArray->getNextIndexOfObject(blockedObject, 0);
5686 	if (pendingResponseTimeout == 0) {
5687 		blockedObject->fPendingResponseDeadline = 0;
5688 		if (i == (unsigned int)-1) {
5689 			goto exit;
5690 		}
5691 		fBlockedArray->removeObject(i);
5692 	} else {
5693 		// Set deadline 2secs after the expected response timeout to allow
5694 		// ack timer to handle the timeout.
5695 		clock_interval_to_deadline(pendingResponseTimeout + 2, kSecondScale, &deadline);
5696 
5697 		if (i != (unsigned int)-1) {
5698 			PM_ERROR("WDOG:Object %s is already blocked for responses. Ignoring timeout %d\n",
5699 			    fName, pendingResponseTimeout);
5700 			goto exit;
5701 		}
5702 
5703 		for (i = 0; i < fBlockedArray->getCount(); i++) {
5704 			obj = OSDynamicCast(IOService, fBlockedArray->getObject(i));
5705 			if (obj && (obj->fPendingResponseDeadline < deadline)) {
5706 				blockedObject->fPendingResponseDeadline = deadline;
5707 				fBlockedArray->setObject(i, blockedObject);
5708 				break;
5709 			}
5710 		}
5711 		if (i == fBlockedArray->getCount()) {
5712 			blockedObject->fPendingResponseDeadline = deadline;
5713 			fBlockedArray->setObject(blockedObject);
5714 		}
5715 	}
5716 
5717 	obj = OSDynamicCast(IOService, fBlockedArray->getObject(0));
5718 	if (!obj) {
5719 		int timeout = getPMRootDomain()->getWatchdogTimeout();
5720 		clock_interval_to_deadline(timeout, kSecondScale, &deadline);
5721 	} else {
5722 		deadline = obj->fPendingResponseDeadline;
5723 	}
5724 
5725 	thread_call_cancel(fWatchdogTimer);
5726 	start_watchdog_timer(deadline);
5727 
5728 exit:
5729 	IOLockUnlock(fWatchdogLock);
5730 }
5731 
5732 
5733 //*********************************************************************************
5734 // [static] watchdog_timer_expired
5735 //
5736 // Inside PM work loop's gate.
5737 //*********************************************************************************
5738 
5739 void
watchdog_timer_expired(thread_call_param_t arg0,thread_call_param_t arg1)5740 IOService::watchdog_timer_expired( thread_call_param_t arg0, thread_call_param_t arg1 )
5741 {
5742 	IOService * me = (IOService *) arg0;
5743 	bool expired;
5744 
5745 	IOLockLock(me->fWatchdogLock);
5746 	expired = me->fWatchdogDeadline && (me->fWatchdogDeadline <= mach_absolute_time());
5747 	IOLockUnlock(me->fWatchdogLock);
5748 	if (!expired) {
5749 		return;
5750 	}
5751 
5752 	gIOPMWatchDogThread = current_thread();
5753 	getPMRootDomain()->sleepWakeDebugTrig(true);
5754 	gIOPMWatchDogThread = NULL;
5755 	thread_call_free(me->fWatchdogTimer);
5756 	me->fWatchdogTimer = NULL;
5757 
5758 	return;
5759 }
5760 
5761 
5762 IOWorkLoop *
getIOPMWorkloop(void)5763 IOService::getIOPMWorkloop( void )
5764 {
5765 	return gIOPMWorkLoop;
5766 }
5767 
5768 
5769 
5770 //*********************************************************************************
5771 // [private] start_ack_timer
5772 //*********************************************************************************
5773 
5774 void
start_ack_timer(void)5775 IOService::start_ack_timer( void )
5776 {
5777 	start_ack_timer( ACK_TIMER_PERIOD, kNanosecondScale );
5778 }
5779 
5780 void
start_ack_timer(UInt32 interval,UInt32 scale)5781 IOService::start_ack_timer( UInt32 interval, UInt32 scale )
5782 {
5783 	AbsoluteTime    deadline;
5784 	boolean_t       pending;
5785 
5786 	clock_interval_to_deadline(interval, scale, &deadline);
5787 
5788 	retain();
5789 	pending = thread_call_enter_delayed(fAckTimer, deadline);
5790 	if (pending) {
5791 		release();
5792 	}
5793 }
5794 
5795 //*********************************************************************************
5796 // [private] stop_ack_timer
5797 //*********************************************************************************
5798 
5799 void
stop_ack_timer(void)5800 IOService::stop_ack_timer( void )
5801 {
5802 	boolean_t   pending;
5803 
5804 	pending = thread_call_cancel(fAckTimer);
5805 	if (pending) {
5806 		release();
5807 	}
5808 }
5809 
5810 //*********************************************************************************
5811 // [static] actionAckTimerExpired
5812 //
5813 // Inside PM work loop's gate.
5814 //*********************************************************************************
5815 
5816 IOReturn
actionAckTimerExpired(OSObject * target,void * arg0,void * arg1,void * arg2,void * arg3)5817 IOService::actionAckTimerExpired(
5818 	OSObject * target,
5819 	void * arg0, void * arg1,
5820 	void * arg2, void * arg3 )
5821 {
5822 	IOService * me = (IOService *) target;
5823 	bool        done;
5824 
5825 	// done will be true if the timer tick unblocks the machine state,
5826 	// otherwise no need to signal the work loop.
5827 
5828 	done = me->ackTimerTick();
5829 	if (done && gIOPMWorkQueue) {
5830 		gIOPMWorkQueue->signalWorkAvailable();
5831 	}
5832 
5833 	return kIOReturnSuccess;
5834 }
5835 
5836 //*********************************************************************************
5837 // ack_timer_expired
5838 //
5839 // Thread call function. Holds a retain while the callout is in flight.
5840 //*********************************************************************************
5841 
5842 void
ack_timer_expired(thread_call_param_t arg0,thread_call_param_t arg1)5843 IOService::ack_timer_expired( thread_call_param_t arg0, thread_call_param_t arg1 )
5844 {
5845 	IOService * me = (IOService *) arg0;
5846 
5847 	if (gIOPMWorkLoop) {
5848 		gIOPMWorkLoop->runAction(&actionAckTimerExpired, me);
5849 	}
5850 	me->release();
5851 }
5852 
5853 
5854 // MARK: -
5855 // MARK: Client Messaging
5856 
5857 //*********************************************************************************
5858 // [private] tellSystemCapabilityChange
5859 //*********************************************************************************
5860 
5861 void
tellSystemCapabilityChange(uint32_t nextMS)5862 IOService::tellSystemCapabilityChange( uint32_t nextMS )
5863 {
5864 	assert(IS_ROOT_DOMAIN);
5865 
5866 	MS_PUSH( nextMS );
5867 	fMachineState       = kIOPM_TellCapabilityChangeDone;
5868 	fOutOfBandMessage   = kIOMessageSystemCapabilityChange;
5869 
5870 	if (fIsPreChange) {
5871 		// Notify app first on pre-change.
5872 		fOutOfBandParameter = kNotifyCapabilityChangeApps;
5873 	} else {
5874 		// Notify kernel clients first on post-change.
5875 		fOutOfBandParameter = kNotifyCapabilityChangePriority;
5876 	}
5877 
5878 	tellClientsWithResponse( fOutOfBandMessage );
5879 }
5880 
5881 //*********************************************************************************
5882 // [public] askChangeDown
5883 //
5884 // Ask registered applications and kernel clients if we can change to a lower
5885 // power state.
5886 //
5887 // Subclass can override this to send a different message type.  Parameter is
5888 // the destination state number.
5889 //
5890 // Return true if we don't have to wait for acknowledgements
5891 //*********************************************************************************
5892 
5893 bool
askChangeDown(unsigned long stateNum)5894 IOService::askChangeDown( unsigned long stateNum )
5895 {
5896 	return tellClientsWithResponse( kIOMessageCanDevicePowerOff );
5897 }
5898 
5899 //*********************************************************************************
5900 // [private] tellChangeDown1
5901 //
5902 // Notify registered applications and kernel clients that we are definitely
5903 // dropping power.
5904 //
5905 // Return true if we don't have to wait for acknowledgements
5906 //*********************************************************************************
5907 
5908 bool
tellChangeDown1(unsigned long stateNum)5909 IOService::tellChangeDown1( unsigned long stateNum )
5910 {
5911 	fOutOfBandParameter = kNotifyApps;
5912 	return tellChangeDown(stateNum);
5913 }
5914 
5915 //*********************************************************************************
5916 // [private] tellChangeDown2
5917 //
5918 // Notify priority clients that we are definitely dropping power.
5919 //
5920 // Return true if we don't have to wait for acknowledgements
5921 //*********************************************************************************
5922 
5923 bool
tellChangeDown2(unsigned long stateNum)5924 IOService::tellChangeDown2( unsigned long stateNum )
5925 {
5926 	fOutOfBandParameter = kNotifyPriority;
5927 	return tellChangeDown(stateNum);
5928 }
5929 
5930 //*********************************************************************************
5931 // [public] tellChangeDown
5932 //
5933 // Notify registered applications and kernel clients that we are definitely
5934 // dropping power.
5935 //
5936 // Subclass can override this to send a different message type.  Parameter is
5937 // the destination state number.
5938 //
5939 // Return true if we don't have to wait for acknowledgements
5940 //*********************************************************************************
5941 
5942 bool
tellChangeDown(unsigned long stateNum)5943 IOService::tellChangeDown( unsigned long stateNum )
5944 {
5945 	return tellClientsWithResponse( kIOMessageDeviceWillPowerOff );
5946 }
5947 
5948 //*********************************************************************************
5949 // cleanClientResponses
5950 //
5951 //*********************************************************************************
5952 
5953 static void
logAppTimeouts(OSObject * object,void * arg)5954 logAppTimeouts( OSObject * object, void * arg )
5955 {
5956 	IOPMInterestContext *   context = (IOPMInterestContext *) arg;
5957 	OSObject *              flag;
5958 	unsigned int            clientIndex;
5959 	int                     pid = 0;
5960 	char                    name[128];
5961 
5962 	if (OSDynamicCast(_IOServiceInterestNotifier, object)) {
5963 		// Discover the 'counter' value or index assigned to this client
5964 		// when it was notified, by searching for the array index of the
5965 		// client in an array holding the cached interested clients.
5966 
5967 		clientIndex = context->notifyClients->getNextIndexOfObject(object, 0);
5968 
5969 		if ((clientIndex != (unsigned int) -1) &&
5970 		    (flag = context->responseArray->getObject(clientIndex)) &&
5971 		    (flag != kOSBooleanTrue)) {
5972 			OSNumber *clientID = copyClientIDForNotification(object, context);
5973 
5974 			name[0] = '\0';
5975 			if (clientID) {
5976 				pid = clientID->unsigned32BitValue();
5977 				proc_name(pid, name, sizeof(name));
5978 				clientID->release();
5979 			}
5980 
5981 			PM_ERROR(context->errorLog, pid, name);
5982 
5983 			// TODO: record message type if possible
5984 			IOService::getPMRootDomain()->pmStatsRecordApplicationResponse(
5985 				gIOPMStatsResponseTimedOut,
5986 				name, 0, (30 * 1000), pid, object);
5987 		}
5988 	}
5989 }
5990 
5991 void
cleanClientResponses(bool logErrors)5992 IOService::cleanClientResponses( bool logErrors )
5993 {
5994 	if (logErrors && fResponseArray) {
5995 		switch (fOutOfBandParameter) {
5996 		case kNotifyApps:
5997 		case kNotifyCapabilityChangeApps:
5998 			if (fNotifyClientArray) {
5999 				IOPMInterestContext context;
6000 
6001 				context.responseArray    = fResponseArray;
6002 				context.notifyClients    = fNotifyClientArray;
6003 				context.serialNumber     = fSerialNumber;
6004 				context.messageType      = kIOMessageCopyClientID;
6005 				context.notifyType       = kNotifyApps;
6006 				context.isPreChange      = fIsPreChange;
6007 				context.enableTracing    = false;
6008 				context.us               = this;
6009 				context.maxTimeRequested = 0;
6010 				context.stateNumber      = fHeadNotePowerState;
6011 				context.stateFlags       = fHeadNotePowerArrayEntry->capabilityFlags;
6012 				context.changeFlags      = fHeadNoteChangeFlags;
6013 				context.errorLog         = "PM notification timeout (pid %d, %s)\n";
6014 
6015 				applyToInterested(gIOAppPowerStateInterest, logAppTimeouts, (void *) &context);
6016 			}
6017 			break;
6018 
6019 		default:
6020 			// kNotifyPriority, kNotifyCapabilityChangePriority
6021 			// TODO: identify the priority client that has not acked
6022 			PM_ERROR("PM priority notification timeout\n");
6023 			if (gIOKitDebug & kIOLogDebugPower) {
6024 				panic("PM priority notification timeout");
6025 			}
6026 			break;
6027 		}
6028 	}
6029 
6030 	if (IS_ROOT_DOMAIN) {
6031 		getPMRootDomain()->reset_watchdog_timer(this, 0);
6032 	}
6033 	if (fResponseArray) {
6034 		fResponseArray->release();
6035 		fResponseArray = NULL;
6036 	}
6037 	if (fNotifyClientArray) {
6038 		fNotifyClientArray->release();
6039 		fNotifyClientArray = NULL;
6040 	}
6041 }
6042 
6043 //*********************************************************************************
6044 // [protected] tellClientsWithResponse
6045 //
6046 // Notify registered applications and kernel clients that we are definitely
6047 // dropping power.
6048 //
6049 // Return true if we don't have to wait for acknowledgements
6050 //*********************************************************************************
6051 
6052 bool
tellClientsWithResponse(int messageType)6053 IOService::tellClientsWithResponse( int messageType )
6054 {
6055 	IOPMInterestContext     context;
6056 	bool                    isRootDomain = IS_ROOT_DOMAIN;
6057 	uint32_t                maxTimeOut = kMaxTimeRequested;
6058 
6059 	PM_ASSERT_IN_GATE();
6060 	assert( fResponseArray == NULL );
6061 	assert( fNotifyClientArray == NULL );
6062 
6063 	RD_LOG("tellClientsWithResponse( %s, %s )\n", getIOMessageString(messageType),
6064 	    getNotificationPhaseString(fOutOfBandParameter));
6065 
6066 	fResponseArray = OSArray::withCapacity( 1 );
6067 	if (!fResponseArray) {
6068 		goto exit;
6069 	}
6070 
6071 	fResponseArray->setCapacityIncrement(8);
6072 	if (++fSerialNumber == 0) {
6073 		fSerialNumber++;
6074 	}
6075 
6076 	context.responseArray    = fResponseArray;
6077 	context.notifyClients    = NULL;
6078 	context.serialNumber     = fSerialNumber;
6079 	context.messageType      = messageType;
6080 	context.notifyType       = fOutOfBandParameter;
6081 	context.skippedInDark    = 0;
6082 	context.notSkippedInDark = 0;
6083 	context.isPreChange      = fIsPreChange;
6084 	context.enableTracing    = false;
6085 	context.us               = this;
6086 	context.maxTimeRequested = 0;
6087 	context.stateNumber      = fHeadNotePowerState;
6088 	context.stateFlags       = fHeadNotePowerArrayEntry->capabilityFlags;
6089 	context.changeFlags      = fHeadNoteChangeFlags;
6090 	context.messageFilter    = (isRootDomain) ?
6091 	    OSMemberFunctionCast(
6092 		IOPMMessageFilter,
6093 		(IOPMrootDomain *)this,
6094 		&IOPMrootDomain::systemMessageFilter) : NULL;
6095 
6096 	switch (fOutOfBandParameter) {
6097 	case kNotifyApps:
6098 		applyToInterested( gIOAppPowerStateInterest,
6099 		    pmTellAppWithResponse, (void *) &context );
6100 
6101 		if (isRootDomain &&
6102 		    (fMachineState != kIOPM_OurChangeTellClientsPowerDown) &&
6103 		    (fMachineState != kIOPM_SyncTellClientsPowerDown) &&
6104 		    (context.messageType != kIOPMMessageLastCallBeforeSleep)) {
6105 			// Notify capability app for tellChangeDown1()
6106 			// but not for askChangeDown().
6107 			context.notifyType  = kNotifyCapabilityChangeApps;
6108 			context.messageType = kIOMessageSystemCapabilityChange;
6109 			applyToInterested( gIOAppPowerStateInterest,
6110 			    pmTellCapabilityAppWithResponse, (void *) &context );
6111 			context.notifyType  = fOutOfBandParameter;
6112 			context.messageType = messageType;
6113 		}
6114 		if (context.messageType == kIOMessageCanSystemSleep) {
6115 			maxTimeOut = kCanSleepMaxTimeReq;
6116 			if (gCanSleepTimeout) {
6117 				maxTimeOut = (gCanSleepTimeout * us_per_s);
6118 			}
6119 		}
6120 		context.maxTimeRequested = maxTimeOut;
6121 		context.enableTracing = isRootDomain;
6122 		applyToInterested( gIOGeneralInterest,
6123 		    pmTellClientWithResponse, (void *) &context );
6124 
6125 		break;
6126 
6127 	case kNotifyPriority:
6128 		context.enableTracing = isRootDomain;
6129 		applyToInterested( gIOPriorityPowerStateInterest,
6130 		    pmTellClientWithResponse, (void *) &context );
6131 
6132 		if (isRootDomain) {
6133 			// Notify capability clients for tellChangeDown2().
6134 			context.notifyType  = kNotifyCapabilityChangePriority;
6135 			context.messageType = kIOMessageSystemCapabilityChange;
6136 			applyToInterested( gIOPriorityPowerStateInterest,
6137 			    pmTellCapabilityClientWithResponse, (void *) &context );
6138 		}
6139 		break;
6140 
6141 	case kNotifyCapabilityChangeApps:
6142 		context.enableTracing = isRootDomain;
6143 		applyToInterested( gIOAppPowerStateInterest,
6144 		    pmTellCapabilityAppWithResponse, (void *) &context );
6145 		if (context.messageType == kIOMessageCanSystemSleep) {
6146 			maxTimeOut = kCanSleepMaxTimeReq;
6147 			if (gCanSleepTimeout) {
6148 				maxTimeOut = (gCanSleepTimeout * us_per_s);
6149 			}
6150 		}
6151 		context.maxTimeRequested = maxTimeOut;
6152 		break;
6153 
6154 	case kNotifyCapabilityChangePriority:
6155 		context.enableTracing = isRootDomain;
6156 		applyToInterested( gIOPriorityPowerStateInterest,
6157 		    pmTellCapabilityClientWithResponse, (void *) &context );
6158 		break;
6159 	}
6160 	fNotifyClientArray = context.notifyClients;
6161 
6162 	if (context.skippedInDark) {
6163 		IOLog("tellClientsWithResponse(%s, %s) %d of %d skipped in dark\n",
6164 		    getIOMessageString(messageType), getNotificationPhaseString(fOutOfBandParameter),
6165 		    context.skippedInDark, context.skippedInDark + context.notSkippedInDark);
6166 	}
6167 
6168 	// do we have to wait for somebody?
6169 	if (!checkForDone()) {
6170 		OUR_PMLog(kPMLogStartAckTimer, context.maxTimeRequested, 0);
6171 		if (context.enableTracing) {
6172 			getPMRootDomain()->traceDetail(context.messageType, 0, context.maxTimeRequested / 1000);
6173 			getPMRootDomain()->reset_watchdog_timer(this, context.maxTimeRequested / USEC_PER_SEC + 1);
6174 		}
6175 		start_ack_timer( context.maxTimeRequested / 1000, kMillisecondScale );
6176 		return false;
6177 	}
6178 
6179 exit:
6180 	// everybody responded
6181 	if (fResponseArray) {
6182 		fResponseArray->release();
6183 		fResponseArray = NULL;
6184 	}
6185 	if (fNotifyClientArray) {
6186 		fNotifyClientArray->release();
6187 		fNotifyClientArray = NULL;
6188 	}
6189 
6190 	return true;
6191 }
6192 
6193 //*********************************************************************************
6194 // [static private] pmTellAppWithResponse
6195 //
6196 // We send a message to an application, and we expect a response, so we compute a
6197 // cookie we can identify the response with.
6198 //*********************************************************************************
6199 
6200 void
pmTellAppWithResponse(OSObject * object,void * arg)6201 IOService::pmTellAppWithResponse( OSObject * object, void * arg )
6202 {
6203 	IOPMInterestContext *   context = (IOPMInterestContext *) arg;
6204 	IOServicePM *           pwrMgt = context->us->pwrMgt;
6205 	uint32_t                msgIndex, msgRef, msgType;
6206 	OSNumber                *clientID = NULL;
6207 	proc_t                  proc = NULL;
6208 	boolean_t               proc_suspended = FALSE;
6209 	OSObject *              waitForReply = kOSBooleanTrue;
6210 #if LOG_APP_RESPONSE_TIMES
6211 	AbsoluteTime            now;
6212 #endif
6213 
6214 	if (!OSDynamicCast(_IOServiceInterestNotifier, object)) {
6215 		return;
6216 	}
6217 
6218 	if (context->us == getPMRootDomain()) {
6219 		if ((clientID = copyClientIDForNotification(object, context))) {
6220 			uint32_t clientPID = clientID->unsigned32BitValue();
6221 			clientID->release();
6222 			proc = proc_find(clientPID);
6223 
6224 			if (proc) {
6225 				proc_suspended = get_task_pidsuspended((task_t) proc->task);
6226 				if (proc_suspended) {
6227 					logClientIDForNotification(object, context, "PMTellAppWithResponse - Suspended");
6228 				} else if (getPMRootDomain()->isAOTMode() && get_task_suspended((task_t) proc->task)) {
6229 					proc_suspended = true;
6230 					context->skippedInDark++;
6231 				}
6232 				proc_rele(proc);
6233 				if (proc_suspended) {
6234 					return;
6235 				}
6236 			}
6237 		}
6238 	}
6239 
6240 	if (context->messageFilter &&
6241 	    !context->messageFilter(context->us, object, context, NULL, &waitForReply)) {
6242 		if (kIOLogDebugPower & gIOKitDebug) {
6243 			logClientIDForNotification(object, context, "DROP App");
6244 		}
6245 		return;
6246 	}
6247 	context->notSkippedInDark++;
6248 
6249 	// Create client array (for tracking purposes) only if the service
6250 	// has app clients. Usually only root domain does.
6251 	if (NULL == context->notifyClients) {
6252 		context->notifyClients = OSArray::withCapacity( 32 );
6253 	}
6254 
6255 	msgType  = context->messageType;
6256 	msgIndex = context->responseArray->getCount();
6257 	msgRef   = ((context->serialNumber & 0xFFFF) << 16) + (msgIndex & 0xFFFF);
6258 
6259 	OUR_PMLog(kPMLogAppNotify, msgType, msgRef);
6260 	if (kIOLogDebugPower & gIOKitDebug) {
6261 		logClientIDForNotification(object, context, "MESG App");
6262 	}
6263 
6264 	if (waitForReply == kOSBooleanTrue) {
6265 		OSNumber * num;
6266 		clock_get_uptime(&now);
6267 		num = OSNumber::withNumber(AbsoluteTime_to_scalar(&now), sizeof(uint64_t) * 8);
6268 		if (num) {
6269 			context->responseArray->setObject(msgIndex, num);
6270 			num->release();
6271 		} else {
6272 			context->responseArray->setObject(msgIndex, kOSBooleanFalse);
6273 		}
6274 	} else {
6275 		context->responseArray->setObject(msgIndex, kOSBooleanTrue);
6276 		if (kIOLogDebugPower & gIOKitDebug) {
6277 			logClientIDForNotification(object, context, "App response ignored");
6278 		}
6279 	}
6280 
6281 	if (context->notifyClients) {
6282 		context->notifyClients->setObject(msgIndex, object);
6283 	}
6284 
6285 	context->us->messageClient(msgType, object, (void *)(uintptr_t) msgRef);
6286 }
6287 
6288 //*********************************************************************************
6289 // [static private] pmTellClientWithResponse
6290 //
6291 // We send a message to an in-kernel client, and we expect a response,
6292 // so we compute a cookie we can identify the response with.
6293 //*********************************************************************************
6294 
6295 void
pmTellClientWithResponse(OSObject * object,void * arg)6296 IOService::pmTellClientWithResponse( OSObject * object, void * arg )
6297 {
6298 	IOPowerStateChangeNotification  notify;
6299 	IOPMInterestContext *           context = (IOPMInterestContext *) arg;
6300 	OSObject *                      replied = kOSBooleanTrue;
6301 	_IOServiceInterestNotifier *    notifier;
6302 	uint32_t                        msgIndex, msgRef, msgType;
6303 	IOReturn                        retCode;
6304 	AbsoluteTime                    start, end;
6305 	uint64_t                        nsec;
6306 	bool                            enableTracing;
6307 
6308 	if (context->messageFilter &&
6309 	    !context->messageFilter(context->us, object, context, NULL, NULL)) {
6310 		getPMRootDomain()->traceFilteredNotification(object);
6311 		return;
6312 	}
6313 
6314 	// Besides interest notifiers this applier function can also be invoked against
6315 	// IOService clients of context->us, so notifier can be NULL. But for tracing
6316 	// purposes the IOService clients can be ignored but each will still consume
6317 	// an entry in the responseArray and also advance msgIndex.
6318 	notifier = OSDynamicCast(_IOServiceInterestNotifier, object);
6319 	msgType  = context->messageType;
6320 	msgIndex = context->responseArray->getCount();
6321 	msgRef   = ((context->serialNumber & 0xFFFF) << 16) + (msgIndex & 0xFFFF);
6322 	enableTracing = context->enableTracing && (notifier != NULL);
6323 
6324 	IOServicePM * pwrMgt = context->us->pwrMgt;
6325 	if (gIOKitDebug & kIOLogPower) {
6326 		OUR_PMLog(kPMLogClientNotify, msgRef, msgType);
6327 		if (OSDynamicCast(IOService, object)) {
6328 			const char *who = ((IOService *) object)->getName();
6329 			gPlatform->PMLog(who, kPMLogClientNotify, (uintptr_t) object, 0);
6330 		} else if (notifier) {
6331 			OUR_PMLog(kPMLogClientNotify, (uintptr_t) notifier->handler, 0);
6332 		}
6333 	}
6334 
6335 	if (NULL == context->notifyClients) {
6336 		context->notifyClients = OSArray::withCapacity(32);
6337 		assert(context->notifyClients != NULL);
6338 	}
6339 
6340 	notify.powerRef    = (void *)(uintptr_t) msgRef;
6341 	notify.returnValue = 0;
6342 	notify.stateNumber = context->stateNumber;
6343 	notify.stateFlags  = context->stateFlags;
6344 
6345 	clock_get_uptime(&start);
6346 	if (enableTracing) {
6347 		getPMRootDomain()->traceNotification(notifier, true, start, msgIndex);
6348 	}
6349 
6350 	retCode = context->us->messageClient(msgType, object, (void *) &notify, sizeof(notify));
6351 
6352 	clock_get_uptime(&end);
6353 	if (enableTracing) {
6354 		getPMRootDomain()->traceNotification(notifier, false, end);
6355 	}
6356 
6357 	if (kIOReturnSuccess == retCode) {
6358 		if (0 == notify.returnValue) {
6359 			OUR_PMLog(kPMLogClientAcknowledge, msgRef, (uintptr_t) object);
6360 			context->responseArray->setObject(msgIndex, replied);
6361 		} else {
6362 			replied = kOSBooleanFalse;
6363 			if (notify.returnValue > context->maxTimeRequested) {
6364 				if (notify.returnValue > kPriorityClientMaxWait) {
6365 					context->maxTimeRequested = kPriorityClientMaxWait;
6366 					PM_ERROR("%s: client %p returned %llu for %s\n",
6367 					    context->us->getName(),
6368 					    notifier ? (void *)  OBFUSCATE(notifier->handler) : OBFUSCATE(object),
6369 					    (uint64_t) notify.returnValue,
6370 					    getIOMessageString(msgType));
6371 				} else {
6372 					context->maxTimeRequested = (typeof(context->maxTimeRequested))notify.returnValue;
6373 				}
6374 			}
6375 			//
6376 			// Track time taken to ack, by storing the timestamp of
6377 			// callback completion
6378 			OSNumber * num;
6379 			num = OSNumber::withNumber(AbsoluteTime_to_scalar(&end), sizeof(uint64_t) * 8);
6380 			if (num) {
6381 				context->responseArray->setObject(msgIndex, num);
6382 				num->release();
6383 			} else {
6384 				context->responseArray->setObject(msgIndex, replied);
6385 			}
6386 		}
6387 
6388 		if (enableTracing) {
6389 			SUB_ABSOLUTETIME(&end, &start);
6390 			absolutetime_to_nanoseconds(end, &nsec);
6391 
6392 			if ((nsec > LOG_KEXT_RESPONSE_TIMES) || (notify.returnValue != 0)) {
6393 				getPMRootDomain()->traceNotificationResponse(notifier, NS_TO_MS(nsec), (uint32_t) notify.returnValue);
6394 			}
6395 		}
6396 	} else {
6397 		// not a client of ours
6398 		// so we won't be waiting for response
6399 		OUR_PMLog(kPMLogClientAcknowledge, msgRef, 0);
6400 		context->responseArray->setObject(msgIndex, replied);
6401 	}
6402 	if (context->notifyClients) {
6403 		context->notifyClients->setObject(msgIndex, object);
6404 	}
6405 }
6406 
6407 //*********************************************************************************
6408 // [static private] pmTellCapabilityAppWithResponse
6409 //*********************************************************************************
6410 
6411 void
pmTellCapabilityAppWithResponse(OSObject * object,void * arg)6412 IOService::pmTellCapabilityAppWithResponse( OSObject * object, void * arg )
6413 {
6414 	IOPMSystemCapabilityChangeParameters msgArg;
6415 	IOPMInterestContext *       context = (IOPMInterestContext *) arg;
6416 	OSObject *                  waitForReply = kOSBooleanFalse;
6417 	IOServicePM *               pwrMgt = context->us->pwrMgt;
6418 	uint32_t                    msgIndex, msgRef, msgType;
6419 #if LOG_APP_RESPONSE_TIMES
6420 	AbsoluteTime                now;
6421 #endif
6422 
6423 	if (!OSDynamicCast(_IOServiceInterestNotifier, object)) {
6424 		return;
6425 	}
6426 
6427 	memset(&msgArg, 0, sizeof(msgArg));
6428 	if (context->messageFilter &&
6429 	    !context->messageFilter(context->us, object, context, &msgArg, &waitForReply)) {
6430 		return;
6431 	}
6432 
6433 	if (context->us == getPMRootDomain() &&
6434 	    getPMRootDomain()->isAOTMode()
6435 	    ) {
6436 		OSNumber                *clientID = NULL;
6437 		boolean_t               proc_suspended = FALSE;
6438 		proc_t                proc = NULL;
6439 		if ((clientID = copyClientIDForNotification(object, context))) {
6440 			uint32_t clientPID = clientID->unsigned32BitValue();
6441 			clientID->release();
6442 			proc = proc_find(clientPID);
6443 			if (proc) {
6444 				proc_suspended = get_task_pidsuspended((task_t) proc->task);
6445 				if (proc_suspended) {
6446 					logClientIDForNotification(object, context, "PMTellCapablityAppWithResponse - Suspended");
6447 				} else if (get_task_suspended((task_t) proc->task)) {
6448 					proc_suspended = true;
6449 					context->skippedInDark++;
6450 				}
6451 				proc_rele(proc);
6452 				if (proc_suspended) {
6453 					return;
6454 				}
6455 			}
6456 		}
6457 	}
6458 	context->notSkippedInDark++;
6459 
6460 	// Create client array (for tracking purposes) only if the service
6461 	// has app clients. Usually only root domain does.
6462 	if (NULL == context->notifyClients) {
6463 		context->notifyClients = OSArray::withCapacity(32);
6464 		assert(context->notifyClients != NULL);
6465 	}
6466 
6467 	msgType  = context->messageType;
6468 	msgIndex = context->responseArray->getCount();
6469 	msgRef   = ((context->serialNumber & 0xFFFF) << 16) + (msgIndex & 0xFFFF);
6470 
6471 	OUR_PMLog(kPMLogAppNotify, msgType, msgRef);
6472 	if (kIOLogDebugPower & gIOKitDebug) {
6473 		// Log client pid/name and client array index.
6474 		OSNumber * clientID = NULL;
6475 		OSString * clientIDString = NULL;
6476 		context->us->messageClient(kIOMessageCopyClientID, object, &clientID);
6477 		if (clientID) {
6478 			clientIDString = IOCopyLogNameForPID(clientID->unsigned32BitValue());
6479 		}
6480 
6481 		PM_LOG("%s MESG App(%u) %s, wait %u, %s\n",
6482 		    context->us->getName(),
6483 		    msgIndex, getIOMessageString(msgType),
6484 		    (waitForReply == kOSBooleanTrue),
6485 		    clientIDString ? clientIDString->getCStringNoCopy() : "");
6486 		if (clientID) {
6487 			clientID->release();
6488 		}
6489 		if (clientIDString) {
6490 			clientIDString->release();
6491 		}
6492 	}
6493 
6494 	msgArg.notifyRef = msgRef;
6495 	msgArg.maxWaitForReply = 0;
6496 
6497 	if (waitForReply == kOSBooleanFalse) {
6498 		msgArg.notifyRef = 0;
6499 		context->responseArray->setObject(msgIndex, kOSBooleanTrue);
6500 		if (context->notifyClients) {
6501 			context->notifyClients->setObject(msgIndex, kOSBooleanTrue);
6502 		}
6503 	} else {
6504 		OSNumber * num;
6505 		clock_get_uptime(&now);
6506 		num = OSNumber::withNumber(AbsoluteTime_to_scalar(&now), sizeof(uint64_t) * 8);
6507 		if (num) {
6508 			context->responseArray->setObject(msgIndex, num);
6509 			num->release();
6510 		} else {
6511 			context->responseArray->setObject(msgIndex, kOSBooleanFalse);
6512 		}
6513 
6514 		if (context->notifyClients) {
6515 			context->notifyClients->setObject(msgIndex, object);
6516 		}
6517 	}
6518 
6519 	context->us->messageClient(msgType, object, (void *) &msgArg, sizeof(msgArg));
6520 }
6521 
6522 //*********************************************************************************
6523 // [static private] pmTellCapabilityClientWithResponse
6524 //*********************************************************************************
6525 
6526 void
pmTellCapabilityClientWithResponse(OSObject * object,void * arg)6527 IOService::pmTellCapabilityClientWithResponse(
6528 	OSObject * object, void * arg )
6529 {
6530 	IOPMSystemCapabilityChangeParameters msgArg;
6531 	IOPMInterestContext *           context = (IOPMInterestContext *) arg;
6532 	OSObject *                      replied = kOSBooleanTrue;
6533 	_IOServiceInterestNotifier *    notifier;
6534 	uint32_t                        msgIndex, msgRef, msgType;
6535 	IOReturn                        retCode;
6536 	AbsoluteTime                    start, end;
6537 	uint64_t                        nsec;
6538 	bool                            enableTracing;
6539 
6540 	memset(&msgArg, 0, sizeof(msgArg));
6541 	if (context->messageFilter &&
6542 	    !context->messageFilter(context->us, object, context, &msgArg, NULL)) {
6543 		getPMRootDomain()->traceFilteredNotification(object);
6544 		return;
6545 	}
6546 
6547 	if (NULL == context->notifyClients) {
6548 		context->notifyClients = OSArray::withCapacity(32);
6549 		assert(context->notifyClients != NULL);
6550 	}
6551 
6552 	notifier = OSDynamicCast(_IOServiceInterestNotifier, object);
6553 	msgType  = context->messageType;
6554 	msgIndex = context->responseArray->getCount();
6555 	msgRef   = ((context->serialNumber & 0xFFFF) << 16) + (msgIndex & 0xFFFF);
6556 	enableTracing = context->enableTracing && (notifier != NULL);
6557 
6558 	IOServicePM * pwrMgt = context->us->pwrMgt;
6559 	if (gIOKitDebug & kIOLogPower) {
6560 		OUR_PMLog(kPMLogClientNotify, msgRef, msgType);
6561 		if (OSDynamicCast(IOService, object)) {
6562 			const char *who = ((IOService *) object)->getName();
6563 			gPlatform->PMLog(who, kPMLogClientNotify, (uintptr_t) object, 0);
6564 		} else if (notifier) {
6565 			OUR_PMLog(kPMLogClientNotify, (uintptr_t) notifier->handler, 0);
6566 		}
6567 	}
6568 
6569 	msgArg.notifyRef = msgRef;
6570 	msgArg.maxWaitForReply = 0;
6571 
6572 	clock_get_uptime(&start);
6573 	if (enableTracing) {
6574 		getPMRootDomain()->traceNotification(notifier, true, start, msgIndex);
6575 	}
6576 
6577 	retCode = context->us->messageClient(msgType, object, (void *) &msgArg, sizeof(msgArg));
6578 
6579 	clock_get_uptime(&end);
6580 	if (enableTracing) {
6581 		getPMRootDomain()->traceNotification(notifier, false, end, msgIndex);
6582 	}
6583 
6584 	if (kIOReturnSuccess == retCode) {
6585 		if (0 == msgArg.maxWaitForReply) {
6586 			// client doesn't want time to respond
6587 			OUR_PMLog(kPMLogClientAcknowledge, msgRef, (uintptr_t) object);
6588 			context->responseArray->setObject(msgIndex, replied);
6589 		} else {
6590 			replied = kOSBooleanFalse;
6591 			if (msgArg.maxWaitForReply > context->maxTimeRequested) {
6592 				if (msgArg.maxWaitForReply > kCapabilityClientMaxWait) {
6593 					context->maxTimeRequested = kCapabilityClientMaxWait;
6594 					PM_ERROR("%s: client %p returned %u for %s\n",
6595 					    context->us->getName(),
6596 					    notifier ? (void *) OBFUSCATE(notifier->handler) : OBFUSCATE(object),
6597 					    msgArg.maxWaitForReply,
6598 					    getIOMessageString(msgType));
6599 				} else {
6600 					context->maxTimeRequested = msgArg.maxWaitForReply;
6601 				}
6602 			}
6603 
6604 			// Track time taken to ack, by storing the timestamp of
6605 			// callback completion
6606 			OSNumber * num;
6607 			num = OSNumber::withNumber(AbsoluteTime_to_scalar(&end), sizeof(uint64_t) * 8);
6608 			if (num) {
6609 				context->responseArray->setObject(msgIndex, num);
6610 				num->release();
6611 			} else {
6612 				context->responseArray->setObject(msgIndex, replied);
6613 			}
6614 		}
6615 
6616 		if (enableTracing) {
6617 			SUB_ABSOLUTETIME(&end, &start);
6618 			absolutetime_to_nanoseconds(end, &nsec);
6619 
6620 			if ((nsec > LOG_KEXT_RESPONSE_TIMES) || (msgArg.maxWaitForReply != 0)) {
6621 				getPMRootDomain()->traceNotificationResponse(notifier, NS_TO_MS(nsec), msgArg.maxWaitForReply);
6622 			}
6623 		}
6624 	} else {
6625 		// not a client of ours
6626 		// so we won't be waiting for response
6627 		OUR_PMLog(kPMLogClientAcknowledge, msgRef, 0);
6628 		context->responseArray->setObject(msgIndex, replied);
6629 	}
6630 	if (context->notifyClients) {
6631 		context->notifyClients->setObject(msgIndex, object);
6632 	}
6633 }
6634 
6635 //*********************************************************************************
6636 // [public] tellNoChangeDown
6637 //
6638 // Notify registered applications and kernel clients that we are not
6639 // dropping power.
6640 //
6641 // Subclass can override this to send a different message type.  Parameter is
6642 // the aborted destination state number.
6643 //*********************************************************************************
6644 
6645 void
tellNoChangeDown(unsigned long)6646 IOService::tellNoChangeDown( unsigned long )
6647 {
6648 	return tellClients( kIOMessageDeviceWillNotPowerOff );
6649 }
6650 
6651 //*********************************************************************************
6652 // [public] tellChangeUp
6653 //
6654 // Notify registered applications and kernel clients that we are raising power.
6655 //
6656 // Subclass can override this to send a different message type.  Parameter is
6657 // the aborted destination state number.
6658 //*********************************************************************************
6659 
6660 void
tellChangeUp(unsigned long)6661 IOService::tellChangeUp( unsigned long )
6662 {
6663 	return tellClients( kIOMessageDeviceHasPoweredOn );
6664 }
6665 
6666 //*********************************************************************************
6667 // [protected] tellClients
6668 //
6669 // Notify registered applications and kernel clients of something.
6670 //*********************************************************************************
6671 
6672 void
tellClients(int messageType)6673 IOService::tellClients( int messageType )
6674 {
6675 	IOPMInterestContext     context;
6676 
6677 	RD_LOG("tellClients( %s )\n", getIOMessageString(messageType));
6678 
6679 	memset(&context, 0, sizeof(context));
6680 	context.messageType   = messageType;
6681 	context.isPreChange   = fIsPreChange;
6682 	context.us            = this;
6683 	context.stateNumber   = fHeadNotePowerState;
6684 	context.stateFlags    = fHeadNotePowerArrayEntry->capabilityFlags;
6685 	context.changeFlags   = fHeadNoteChangeFlags;
6686 	context.enableTracing = IS_ROOT_DOMAIN;
6687 	context.messageFilter = (IS_ROOT_DOMAIN) ?
6688 	    OSMemberFunctionCast(
6689 		IOPMMessageFilter,
6690 		(IOPMrootDomain *)this,
6691 		&IOPMrootDomain::systemMessageFilter) : NULL;
6692 
6693 	context.notifyType = kNotifyPriority;
6694 	applyToInterested( gIOPriorityPowerStateInterest,
6695 	    tellKernelClientApplier, (void *) &context );
6696 
6697 	context.notifyType = kNotifyApps;
6698 	applyToInterested( gIOAppPowerStateInterest,
6699 	    tellAppClientApplier, (void *) &context );
6700 
6701 	applyToInterested( gIOGeneralInterest,
6702 	    tellKernelClientApplier, (void *) &context );
6703 }
6704 
6705 //*********************************************************************************
6706 // [private] tellKernelClientApplier
6707 //
6708 // Message a kernel client.
6709 //*********************************************************************************
6710 
6711 static void
tellKernelClientApplier(OSObject * object,void * arg)6712 tellKernelClientApplier( OSObject * object, void * arg )
6713 {
6714 	IOPowerStateChangeNotification  notify;
6715 	IOPMInterestContext *           context = (IOPMInterestContext *) arg;
6716 	bool                            enableTracing = context->enableTracing;
6717 
6718 	if (context->messageFilter &&
6719 	    !context->messageFilter(context->us, object, context, NULL, NULL)) {
6720 		IOService::getPMRootDomain()->traceFilteredNotification(object);
6721 		return;
6722 	}
6723 
6724 	notify.powerRef     = (void *) NULL;
6725 	notify.returnValue  = 0;
6726 	notify.stateNumber  = context->stateNumber;
6727 	notify.stateFlags   = context->stateFlags;
6728 
6729 	if (enableTracing) {
6730 		IOService::getPMRootDomain()->traceNotification(object, true);
6731 	}
6732 
6733 	context->us->messageClient(context->messageType, object, &notify, sizeof(notify));
6734 
6735 	if (enableTracing) {
6736 		IOService::getPMRootDomain()->traceNotification(object, false);
6737 	}
6738 }
6739 
6740 static OSNumber *
copyClientIDForNotification(OSObject * object,IOPMInterestContext * context)6741 copyClientIDForNotification(
6742 	OSObject *object,
6743 	IOPMInterestContext *context)
6744 {
6745 	OSNumber *clientID = NULL;
6746 	context->us->messageClient(kIOMessageCopyClientID, object, &clientID);
6747 	return clientID;
6748 }
6749 
6750 static void
logClientIDForNotification(OSObject * object,IOPMInterestContext * context,const char * logString)6751 logClientIDForNotification(
6752 	OSObject *object,
6753 	IOPMInterestContext *context,
6754 	const char *logString)
6755 {
6756 	OSString *logClientID = NULL;
6757 	OSNumber *clientID = copyClientIDForNotification(object, context);
6758 
6759 	if (logString) {
6760 		if (clientID) {
6761 			logClientID = IOCopyLogNameForPID(clientID->unsigned32BitValue());
6762 		}
6763 
6764 		PM_LOG("%s %s %s, %s\n",
6765 		    context->us->getName(), logString,
6766 		    IOService::getIOMessageString(context->messageType),
6767 		    logClientID ? logClientID->getCStringNoCopy() : "");
6768 
6769 		if (logClientID) {
6770 			logClientID->release();
6771 		}
6772 	}
6773 
6774 	if (clientID) {
6775 		clientID->release();
6776 	}
6777 
6778 	return;
6779 }
6780 
6781 static void
tellAppClientApplier(OSObject * object,void * arg)6782 tellAppClientApplier( OSObject * object, void * arg )
6783 {
6784 	IOPMInterestContext * context = (IOPMInterestContext *) arg;
6785 	OSNumber            * clientID = NULL;
6786 	proc_t                proc = NULL;
6787 	boolean_t             proc_suspended = FALSE;
6788 
6789 	if (context->us == IOService::getPMRootDomain()) {
6790 		if ((clientID = copyClientIDForNotification(object, context))) {
6791 			uint32_t clientPID = clientID->unsigned32BitValue();
6792 			clientID->release();
6793 			proc = proc_find(clientPID);
6794 
6795 			if (proc) {
6796 				proc_suspended = get_task_pidsuspended((task_t) proc->task);
6797 				if (proc_suspended) {
6798 					logClientIDForNotification(object, context, "tellAppClientApplier - Suspended");
6799 				} else if (IOService::getPMRootDomain()->isAOTMode() && get_task_suspended((task_t) proc->task)) {
6800 					proc_suspended = true;
6801 					context->skippedInDark++;
6802 				}
6803 				proc_rele(proc);
6804 				if (proc_suspended) {
6805 					return;
6806 				}
6807 			}
6808 		}
6809 	}
6810 
6811 	if (context->messageFilter &&
6812 	    !context->messageFilter(context->us, object, context, NULL, NULL)) {
6813 		if (kIOLogDebugPower & gIOKitDebug) {
6814 			logClientIDForNotification(object, context, "DROP App");
6815 		}
6816 		return;
6817 	}
6818 	context->notSkippedInDark++;
6819 
6820 	if (kIOLogDebugPower & gIOKitDebug) {
6821 		logClientIDForNotification(object, context, "MESG App");
6822 	}
6823 
6824 	context->us->messageClient(context->messageType, object, NULL);
6825 }
6826 
6827 //*********************************************************************************
6828 // [private] checkForDone
6829 //*********************************************************************************
6830 
6831 bool
checkForDone(void)6832 IOService::checkForDone( void )
6833 {
6834 	int         i = 0;
6835 	OSObject *  theFlag;
6836 
6837 	if (fResponseArray == NULL) {
6838 		return true;
6839 	}
6840 
6841 	for (i = 0;; i++) {
6842 		theFlag = fResponseArray->getObject(i);
6843 
6844 		if (NULL == theFlag) {
6845 			break;
6846 		}
6847 
6848 		if (kOSBooleanTrue != theFlag) {
6849 			return false;
6850 		}
6851 	}
6852 	return true;
6853 }
6854 
6855 //*********************************************************************************
6856 // [public] responseValid
6857 //*********************************************************************************
6858 
6859 bool
responseValid(uint32_t refcon,int pid)6860 IOService::responseValid( uint32_t refcon, int pid )
6861 {
6862 	UInt16          serialComponent;
6863 	UInt16          ordinalComponent;
6864 	OSObject *      theFlag;
6865 	OSObject        *object = NULL;
6866 
6867 	serialComponent  = (refcon >> 16) & 0xFFFF;
6868 	ordinalComponent = (refcon & 0xFFFF);
6869 
6870 	if (serialComponent != fSerialNumber) {
6871 		return false;
6872 	}
6873 
6874 	if (fResponseArray == NULL) {
6875 		return false;
6876 	}
6877 
6878 	theFlag = fResponseArray->getObject(ordinalComponent);
6879 
6880 	if (theFlag == NULL) {
6881 		return false;
6882 	}
6883 
6884 	if (fNotifyClientArray) {
6885 		object = fNotifyClientArray->getObject(ordinalComponent);
6886 	}
6887 
6888 	OSNumber * num;
6889 	if ((num = OSDynamicCast(OSNumber, theFlag))) {
6890 		AbsoluteTime    now;
6891 		AbsoluteTime    start;
6892 		uint64_t        nsec;
6893 		char            name[128];
6894 
6895 		clock_get_uptime(&now);
6896 		AbsoluteTime_to_scalar(&start) = num->unsigned64BitValue();
6897 		SUB_ABSOLUTETIME(&now, &start);
6898 		absolutetime_to_nanoseconds(now, &nsec);
6899 
6900 		if (pid != 0) {
6901 			name[0] = '\0';
6902 			proc_name(pid, name, sizeof(name));
6903 
6904 			if (nsec > LOG_APP_RESPONSE_TIMES) {
6905 				IOLog("PM response took %d ms (%d, %s)\n", NS_TO_MS(nsec),
6906 				    pid, name);
6907 			}
6908 
6909 			if (nsec > LOG_APP_RESPONSE_MSG_TRACER) {
6910 				// TODO: populate the messageType argument
6911 				getPMRootDomain()->pmStatsRecordApplicationResponse(
6912 					gIOPMStatsResponseSlow,
6913 					name, 0, NS_TO_MS(nsec), pid, object);
6914 			} else {
6915 				getPMRootDomain()->pmStatsRecordApplicationResponse(
6916 					gIOPMStatsResponsePrompt,
6917 					name, 0, NS_TO_MS(nsec), pid, object);
6918 			}
6919 		} else {
6920 			getPMRootDomain()->traceNotificationAck(object, NS_TO_MS(nsec));
6921 		}
6922 
6923 		if (kIOLogDebugPower & gIOKitDebug) {
6924 			PM_LOG("Ack(%u) %u ms\n",
6925 			    (uint32_t) ordinalComponent,
6926 			    NS_TO_MS(nsec));
6927 		}
6928 		theFlag = kOSBooleanFalse;
6929 	} else if (object) {
6930 		getPMRootDomain()->pmStatsRecordApplicationResponse(
6931 			gIOPMStatsResponsePrompt,
6932 			NULL, 0, 0, pid, object);
6933 	}
6934 
6935 	if (kOSBooleanFalse == theFlag) {
6936 		fResponseArray->replaceObject(ordinalComponent, kOSBooleanTrue);
6937 	}
6938 
6939 	return true;
6940 }
6941 
6942 //*********************************************************************************
6943 // [public] allowPowerChange
6944 //
6945 // Our power state is about to lower, and we have notified applications
6946 // and kernel clients, and one of them has acknowledged.  If this is the last to do
6947 // so, and all acknowledgements are positive, we continue with the power change.
6948 //*********************************************************************************
6949 
6950 IOReturn
allowPowerChange(unsigned long refcon)6951 IOService::allowPowerChange( unsigned long refcon )
6952 {
6953 	IOPMRequest * request;
6954 
6955 	if (!initialized) {
6956 		// we're unloading
6957 		return kIOReturnSuccess;
6958 	}
6959 
6960 	request = acquirePMRequest( this, kIOPMRequestTypeAllowPowerChange );
6961 	if (!request) {
6962 		return kIOReturnNoMemory;
6963 	}
6964 
6965 	request->fArg0 = (void *)            refcon;
6966 	request->fArg1 = (void *)(uintptr_t) proc_selfpid();
6967 	request->fArg2 = (void *)            NULL;
6968 	submitPMRequest( request );
6969 
6970 	return kIOReturnSuccess;
6971 }
6972 
6973 #ifndef __LP64__
6974 IOReturn
serializedAllowPowerChange2(unsigned long refcon)6975 IOService::serializedAllowPowerChange2( unsigned long refcon )
6976 {
6977 	// [deprecated] public
6978 	return kIOReturnUnsupported;
6979 }
6980 #endif /* !__LP64__ */
6981 
6982 //*********************************************************************************
6983 // [public] cancelPowerChange
6984 //
6985 // Our power state is about to lower, and we have notified applications
6986 // and kernel clients, and one of them has vetoed the change.  If this is the last
6987 // client to respond, we abandon the power change.
6988 //*********************************************************************************
6989 
6990 IOReturn
cancelPowerChange(unsigned long refcon)6991 IOService::cancelPowerChange( unsigned long refcon )
6992 {
6993 	IOPMRequest *   request;
6994 	char            name[128];
6995 	pid_t           pid = proc_selfpid();
6996 
6997 	if (!initialized) {
6998 		// we're unloading
6999 		return kIOReturnSuccess;
7000 	}
7001 
7002 	name[0] = '\0';
7003 	proc_name(pid, name, sizeof(name));
7004 	PM_ERROR("PM notification cancel (pid %d, %s)\n", pid, name);
7005 
7006 	request = acquirePMRequest( this, kIOPMRequestTypeCancelPowerChange );
7007 	if (!request) {
7008 		return kIOReturnNoMemory;
7009 	}
7010 
7011 	request->fArg0 = (void *)            refcon;
7012 	request->fArg1 = (void *)(uintptr_t) proc_selfpid();
7013 	request->fArg2 = (void *)            OSString::withCString(name);
7014 	submitPMRequest( request );
7015 
7016 	return kIOReturnSuccess;
7017 }
7018 
7019 //*********************************************************************************
7020 // cancelIdlePowerDown
7021 //
7022 // Internal method to trigger an idle cancel or revert
7023 //*********************************************************************************
7024 
7025 void
cancelIdlePowerDown(IOService * service)7026 IOService::cancelIdlePowerDown( IOService * service )
7027 {
7028 	IOPMRequest * request;
7029 
7030 	request = acquirePMRequest(service, kIOPMRequestTypeIdleCancel);
7031 	if (request) {
7032 		submitPMRequest(request);
7033 	}
7034 }
7035 
7036 #ifndef __LP64__
7037 IOReturn
serializedCancelPowerChange2(unsigned long refcon)7038 IOService::serializedCancelPowerChange2( unsigned long refcon )
7039 {
7040 	// [deprecated] public
7041 	return kIOReturnUnsupported;
7042 }
7043 
7044 //*********************************************************************************
7045 // PM_Clamp_Timer_Expired
7046 //
7047 // called when clamp timer expires...set power state to 0.
7048 //*********************************************************************************
7049 
7050 void
PM_Clamp_Timer_Expired(void)7051 IOService::PM_Clamp_Timer_Expired( void )
7052 {
7053 }
7054 
7055 //*********************************************************************************
7056 // clampPowerOn
7057 //
7058 // Set to highest available power state for a minimum of duration milliseconds
7059 //*********************************************************************************
7060 
7061 void
clampPowerOn(unsigned long duration)7062 IOService::clampPowerOn( unsigned long duration )
7063 {
7064 }
7065 #endif /* !__LP64__ */
7066 
7067 //*********************************************************************************
7068 //  configurePowerStateReport
7069 //
7070 //  Configures the IOStateReport for kPMPowerStateChannel
7071 //*********************************************************************************
7072 IOReturn
configurePowerStatesReport(IOReportConfigureAction action,void * result)7073 IOService::configurePowerStatesReport( IOReportConfigureAction action, void *result )
7074 {
7075 	IOReturn rc = kIOReturnSuccess;
7076 	size_t  reportSize;
7077 	unsigned long i;
7078 	uint64_t ts;
7079 
7080 	if (!pwrMgt) {
7081 		return kIOReturnUnsupported;
7082 	}
7083 
7084 	if (!fNumberOfPowerStates) {
7085 		return kIOReturnSuccess; // For drivers which are in power plane, but haven't called registerPowerDriver()
7086 	}
7087 
7088 	if (fNumberOfPowerStates > INT16_MAX) {
7089 		return kIOReturnOverrun;
7090 	}
7091 	PM_LOCK();
7092 
7093 	switch (action) {
7094 	case kIOReportEnable:
7095 		if (fReportBuf) {
7096 			fReportClientCnt++;
7097 			break;
7098 		}
7099 		reportSize = STATEREPORT_BUFSIZE(fNumberOfPowerStates);
7100 		fReportBuf = IOMallocZeroData(reportSize);
7101 		if (!fReportBuf) {
7102 			rc = kIOReturnNoMemory;
7103 			break;
7104 		}
7105 
7106 		STATEREPORT_INIT((uint16_t) fNumberOfPowerStates, fReportBuf, reportSize,
7107 		    getRegistryEntryID(), kPMPowerStatesChID, kIOReportCategoryPower);
7108 
7109 		for (i = 0; i < fNumberOfPowerStates; i++) {
7110 			unsigned bits = 0;
7111 
7112 			if (fPowerStates[i].capabilityFlags & kIOPMPowerOn) {
7113 				bits |= kPMReportPowerOn;
7114 			}
7115 			if (fPowerStates[i].capabilityFlags & kIOPMDeviceUsable) {
7116 				bits |= kPMReportDeviceUsable;
7117 			}
7118 			if (fPowerStates[i].capabilityFlags & kIOPMLowPower) {
7119 				bits |= kPMReportLowPower;
7120 			}
7121 
7122 			STATEREPORT_SETSTATEID(fReportBuf, i, ((bits & 0xff) << 8) |
7123 			    ((StateOrder(fMaxPowerState) & 0xf) << 4) | (StateOrder(i) & 0xf));
7124 		}
7125 		ts = mach_absolute_time();
7126 		STATEREPORT_SETSTATE(fReportBuf, (uint16_t) fCurrentPowerState, ts);
7127 		break;
7128 
7129 	case kIOReportDisable:
7130 		if (fReportClientCnt == 0) {
7131 			rc = kIOReturnBadArgument;
7132 			break;
7133 		}
7134 		if (fReportClientCnt == 1) {
7135 			IOFreeData(fReportBuf, STATEREPORT_BUFSIZE(fNumberOfPowerStates));
7136 			fReportBuf = NULL;
7137 		}
7138 		fReportClientCnt--;
7139 		break;
7140 
7141 	case kIOReportGetDimensions:
7142 		if (fReportBuf) {
7143 			STATEREPORT_UPDATERES(fReportBuf, kIOReportGetDimensions, result);
7144 		}
7145 		break;
7146 	}
7147 
7148 	PM_UNLOCK();
7149 
7150 	return rc;
7151 }
7152 
7153 //*********************************************************************************
7154 //  updatePowerStateReport
7155 //
7156 //  Updates the IOStateReport for kPMPowerStateChannel
7157 //*********************************************************************************
7158 IOReturn
updatePowerStatesReport(IOReportConfigureAction action,void * result,void * destination)7159 IOService::updatePowerStatesReport( IOReportConfigureAction action, void *result, void *destination )
7160 {
7161 	uint32_t size2cpy;
7162 	void *data2cpy;
7163 	uint64_t ts;
7164 	IOReturn rc = kIOReturnSuccess;
7165 	IOBufferMemoryDescriptor *dest = OSDynamicCast(IOBufferMemoryDescriptor, (OSObject *)destination);
7166 
7167 
7168 	if (!pwrMgt) {
7169 		return kIOReturnUnsupported;
7170 	}
7171 	if (!fNumberOfPowerStates) {
7172 		return kIOReturnSuccess;
7173 	}
7174 
7175 	if (!result || !dest) {
7176 		return kIOReturnBadArgument;
7177 	}
7178 	PM_LOCK();
7179 
7180 	switch (action) {
7181 	case kIOReportCopyChannelData:
7182 		if (!fReportBuf) {
7183 			rc = kIOReturnNotOpen;
7184 			break;
7185 		}
7186 
7187 		ts = mach_absolute_time();
7188 		STATEREPORT_UPDATEPREP(fReportBuf, ts, data2cpy, size2cpy);
7189 		if (size2cpy > (dest->getCapacity() - dest->getLength())) {
7190 			rc = kIOReturnOverrun;
7191 			break;
7192 		}
7193 
7194 		STATEREPORT_UPDATERES(fReportBuf, kIOReportCopyChannelData, result);
7195 		dest->appendBytes(data2cpy, size2cpy);
7196 		break;
7197 
7198 	default:
7199 		break;
7200 	}
7201 
7202 	PM_UNLOCK();
7203 
7204 	return rc;
7205 }
7206 
7207 //*********************************************************************************
7208 //  configureSimplePowerReport
7209 //
7210 //  Configures the IOSimpleReport for given channel id
7211 //*********************************************************************************
7212 IOReturn
configureSimplePowerReport(IOReportConfigureAction action,void * result)7213 IOService::configureSimplePowerReport(IOReportConfigureAction action, void *result )
7214 {
7215 	IOReturn rc = kIOReturnSuccess;
7216 
7217 	if (!pwrMgt) {
7218 		return kIOReturnUnsupported;
7219 	}
7220 
7221 	if (!fNumberOfPowerStates) {
7222 		return rc;
7223 	}
7224 
7225 	switch (action) {
7226 	case kIOReportEnable:
7227 	case kIOReportDisable:
7228 		break;
7229 
7230 	case kIOReportGetDimensions:
7231 		SIMPLEREPORT_UPDATERES(kIOReportGetDimensions, result);
7232 		break;
7233 	}
7234 
7235 
7236 	return rc;
7237 }
7238 
7239 //*********************************************************************************
7240 //  updateSimplePowerReport
7241 //
7242 //  Updates the IOSimpleReport for the given chanel id
7243 //*********************************************************************************
7244 IOReturn
updateSimplePowerReport(IOReportConfigureAction action,void * result,void * destination)7245 IOService::updateSimplePowerReport( IOReportConfigureAction action, void *result, void *destination )
7246 {
7247 	uint32_t size2cpy;
7248 	void *data2cpy;
7249 	uint64_t buf[SIMPLEREPORT_BUFSIZE / sizeof(uint64_t) + 1]; // Force a 8-byte alignment
7250 	IOBufferMemoryDescriptor *dest = OSDynamicCast(IOBufferMemoryDescriptor, (OSObject *)destination);
7251 	IOReturn rc = kIOReturnSuccess;
7252 	unsigned bits = 0;
7253 
7254 
7255 	if (!pwrMgt) {
7256 		return kIOReturnUnsupported;
7257 	}
7258 	if (!result || !dest) {
7259 		return kIOReturnBadArgument;
7260 	}
7261 
7262 	if (!fNumberOfPowerStates) {
7263 		return rc;
7264 	}
7265 	PM_LOCK();
7266 
7267 	switch (action) {
7268 	case kIOReportCopyChannelData:
7269 
7270 		SIMPLEREPORT_INIT(buf, sizeof(buf), getRegistryEntryID(), kPMCurrStateChID, kIOReportCategoryPower);
7271 
7272 		if (fPowerStates[fCurrentPowerState].capabilityFlags & kIOPMPowerOn) {
7273 			bits |= kPMReportPowerOn;
7274 		}
7275 		if (fPowerStates[fCurrentPowerState].capabilityFlags & kIOPMDeviceUsable) {
7276 			bits |= kPMReportDeviceUsable;
7277 		}
7278 		if (fPowerStates[fCurrentPowerState].capabilityFlags & kIOPMLowPower) {
7279 			bits |= kPMReportLowPower;
7280 		}
7281 
7282 
7283 		SIMPLEREPORT_SETVALUE(buf, ((bits & 0xff) << 8) | ((StateOrder(fMaxPowerState) & 0xf) << 4) |
7284 		    (StateOrder(fCurrentPowerState) & 0xf));
7285 
7286 		SIMPLEREPORT_UPDATEPREP(buf, data2cpy, size2cpy);
7287 		if (size2cpy > (dest->getCapacity() - dest->getLength())) {
7288 			rc = kIOReturnOverrun;
7289 			break;
7290 		}
7291 
7292 		SIMPLEREPORT_UPDATERES(kIOReportCopyChannelData, result);
7293 		dest->appendBytes(data2cpy, size2cpy);
7294 		break;
7295 
7296 	default:
7297 		break;
7298 	}
7299 
7300 	PM_UNLOCK();
7301 
7302 	return rc;
7303 }
7304 
7305 
7306 
7307 // MARK: -
7308 // MARK: Driver Overrides
7309 
7310 //*********************************************************************************
7311 // [public] setPowerState
7312 //
7313 // Does nothing here.  This should be implemented in a subclass driver.
7314 //*********************************************************************************
7315 
7316 IOReturn
setPowerState(unsigned long powerStateOrdinal,IOService * whatDevice)7317 IOService::setPowerState(
7318 	unsigned long powerStateOrdinal, IOService * whatDevice )
7319 {
7320 	return IOPMNoErr;
7321 }
7322 
7323 //*********************************************************************************
7324 // [public] maxCapabilityForDomainState
7325 //
7326 // Finds the highest power state in the array whose input power requirement
7327 // is equal to the input parameter. Where a more intelligent decision is
7328 // possible, override this in the subclassed driver.
7329 //*********************************************************************************
7330 
7331 IOPMPowerStateIndex
getPowerStateForDomainFlags(IOPMPowerFlags flags)7332 IOService::getPowerStateForDomainFlags( IOPMPowerFlags flags )
7333 {
7334 	IOPMPowerStateIndex stateIndex;
7335 
7336 	if (!fNumberOfPowerStates) {
7337 		return kPowerStateZero;
7338 	}
7339 
7340 	for (long order = fNumberOfPowerStates - 1; order >= 0; order--) {
7341 		stateIndex = fPowerStates[order].stateOrderToIndex;
7342 
7343 		if ((flags & fPowerStates[stateIndex].inputPowerFlags) ==
7344 		    fPowerStates[stateIndex].inputPowerFlags) {
7345 			return stateIndex;
7346 		}
7347 	}
7348 	return kPowerStateZero;
7349 }
7350 
7351 unsigned long
maxCapabilityForDomainState(IOPMPowerFlags domainState)7352 IOService::maxCapabilityForDomainState( IOPMPowerFlags domainState )
7353 {
7354 	return getPowerStateForDomainFlags(domainState);
7355 }
7356 
7357 //*********************************************************************************
7358 // [public] initialPowerStateForDomainState
7359 //
7360 // Called to query the power state for the initial power transition.
7361 //*********************************************************************************
7362 
7363 unsigned long
initialPowerStateForDomainState(IOPMPowerFlags domainState)7364 IOService::initialPowerStateForDomainState( IOPMPowerFlags domainState )
7365 {
7366 	if (fResetPowerStateOnWake && (domainState & kIOPMRootDomainState)) {
7367 		// Return lowest power state for any root power domain changes
7368 		return kPowerStateZero;
7369 	}
7370 
7371 	return getPowerStateForDomainFlags(domainState);
7372 }
7373 
7374 //*********************************************************************************
7375 // [public] powerStateForDomainState
7376 //
7377 // This method is not called from PM.
7378 //*********************************************************************************
7379 
7380 unsigned long
powerStateForDomainState(IOPMPowerFlags domainState)7381 IOService::powerStateForDomainState( IOPMPowerFlags domainState )
7382 {
7383 	return getPowerStateForDomainFlags(domainState);
7384 }
7385 
7386 #ifndef __LP64__
7387 //*********************************************************************************
7388 // [deprecated] didYouWakeSystem
7389 //
7390 // Does nothing here.  This should be implemented in a subclass driver.
7391 //*********************************************************************************
7392 
7393 bool
didYouWakeSystem(void)7394 IOService::didYouWakeSystem( void )
7395 {
7396 	return false;
7397 }
7398 #endif /* !__LP64__ */
7399 
7400 //*********************************************************************************
7401 // [public] powerStateWillChangeTo
7402 //
7403 // Does nothing here.  This should be implemented in a subclass driver.
7404 //*********************************************************************************
7405 
7406 IOReturn
powerStateWillChangeTo(IOPMPowerFlags,unsigned long,IOService *)7407 IOService::powerStateWillChangeTo( IOPMPowerFlags, unsigned long, IOService * )
7408 {
7409 	return kIOPMAckImplied;
7410 }
7411 
7412 //*********************************************************************************
7413 // [public] powerStateDidChangeTo
7414 //
7415 // Does nothing here.  This should be implemented in a subclass driver.
7416 //*********************************************************************************
7417 
7418 IOReturn
powerStateDidChangeTo(IOPMPowerFlags,unsigned long,IOService *)7419 IOService::powerStateDidChangeTo( IOPMPowerFlags, unsigned long, IOService * )
7420 {
7421 	return kIOPMAckImplied;
7422 }
7423 
7424 //*********************************************************************************
7425 // [protected] powerChangeDone
7426 //
7427 // Called from PM work loop thread.
7428 // Does nothing here.  This should be implemented in a subclass policy-maker.
7429 //*********************************************************************************
7430 
7431 void
powerChangeDone(unsigned long)7432 IOService::powerChangeDone( unsigned long )
7433 {
7434 }
7435 
7436 #ifndef __LP64__
7437 //*********************************************************************************
7438 // [deprecated] newTemperature
7439 //
7440 // Does nothing here.  This should be implemented in a subclass driver.
7441 //*********************************************************************************
7442 
7443 IOReturn
newTemperature(long currentTemp,IOService * whichZone)7444 IOService::newTemperature( long currentTemp, IOService * whichZone )
7445 {
7446 	return IOPMNoErr;
7447 }
7448 #endif /* !__LP64__ */
7449 
7450 //*********************************************************************************
7451 // [public] systemWillShutdown
7452 //
7453 // System shutdown and restart notification.
7454 //*********************************************************************************
7455 
7456 void
systemWillShutdown(IOOptionBits specifier)7457 IOService::systemWillShutdown( IOOptionBits specifier )
7458 {
7459 	IOPMrootDomain * rootDomain = IOService::getPMRootDomain();
7460 	if (rootDomain) {
7461 		rootDomain->acknowledgeSystemWillShutdown( this );
7462 	}
7463 }
7464 
7465 // MARK: -
7466 // MARK: PM State Machine
7467 
7468 //*********************************************************************************
7469 // [private static] acquirePMRequest
7470 //*********************************************************************************
7471 
7472 IOPMRequest *
acquirePMRequest(IOService * target,IOOptionBits requestType,IOPMRequest * active)7473 IOService::acquirePMRequest( IOService * target, IOOptionBits requestType,
7474     IOPMRequest * active )
7475 {
7476 	IOPMRequest * request;
7477 
7478 	assert(target);
7479 
7480 	request = IOPMRequest::create();
7481 	if (request) {
7482 		request->init( target, requestType );
7483 		if (active) {
7484 			IOPMRequest * root = active->getRootRequest();
7485 			if (root) {
7486 				request->attachRootRequest(root);
7487 			}
7488 		}
7489 	} else {
7490 		PM_ERROR("%s: No memory for PM request type 0x%x\n",
7491 		    target->getName(), (uint32_t) requestType);
7492 	}
7493 	return request;
7494 }
7495 
7496 //*********************************************************************************
7497 // [private static] releasePMRequest
7498 //*********************************************************************************
7499 
7500 void
releasePMRequest(IOPMRequest * request)7501 IOService::releasePMRequest( IOPMRequest * request )
7502 {
7503 	if (request) {
7504 		request->reset();
7505 		request->release();
7506 	}
7507 }
7508 
7509 //*********************************************************************************
7510 // [private static] submitPMRequest
7511 //*********************************************************************************
7512 
7513 void
submitPMRequest(IOPMRequest * request)7514 IOService::submitPMRequest( IOPMRequest * request )
7515 {
7516 	assert( request );
7517 	assert( gIOPMReplyQueue );
7518 	assert( gIOPMRequestQueue );
7519 
7520 	PM_LOG1("[+ %02lx] %p [%p %s] %p %p %p\n",
7521 	    (long)request->getType(), OBFUSCATE(request),
7522 	    OBFUSCATE(request->getTarget()), request->getTarget()->getName(),
7523 	    OBFUSCATE(request->fArg0),
7524 	    OBFUSCATE(request->fArg1), OBFUSCATE(request->fArg2));
7525 
7526 	if (request->isReplyType()) {
7527 		gIOPMReplyQueue->queuePMRequest( request );
7528 	} else {
7529 		gIOPMRequestQueue->queuePMRequest( request );
7530 	}
7531 }
7532 
7533 void
submitPMRequests(IOPMRequest ** requests,IOItemCount count)7534 IOService::submitPMRequests( IOPMRequest ** requests, IOItemCount count )
7535 {
7536 	assert( requests );
7537 	assert( count > 0 );
7538 	assert( gIOPMRequestQueue );
7539 
7540 	for (IOItemCount i = 0; i < count; i++) {
7541 		IOPMRequest * req = requests[i];
7542 		PM_LOG1("[+ %02lx] %p [%p %s] %p %p %p\n",
7543 		    (long)req->getType(), OBFUSCATE(req),
7544 		    OBFUSCATE(req->getTarget()), req->getTarget()->getName(),
7545 		    OBFUSCATE(req->fArg0),
7546 		    OBFUSCATE(req->fArg1), OBFUSCATE(req->fArg2));
7547 	}
7548 
7549 	gIOPMRequestQueue->queuePMRequestChain( requests, count );
7550 }
7551 
7552 //*********************************************************************************
7553 // [private] actionPMRequestQueue
7554 //
7555 // IOPMRequestQueue::checkForWork() passing a new request to the request target.
7556 //*********************************************************************************
7557 
7558 bool
actionPMRequestQueue(IOPMRequest * request,IOPMRequestQueue * queue)7559 IOService::actionPMRequestQueue(
7560 	IOPMRequest *       request,
7561 	IOPMRequestQueue *  queue )
7562 {
7563 	bool more;
7564 
7565 	if (initialized) {
7566 		// Work queue will immediately execute the request if the per-service
7567 		// request queue is empty. Note pwrMgt is the target's IOServicePM.
7568 
7569 		more = gIOPMWorkQueue->queuePMRequest(request, pwrMgt);
7570 	} else {
7571 		// Calling PM without PMinit() is not allowed, fail the request.
7572 		// Need to signal more when completing attached requests.
7573 
7574 		PM_LOG("%s: PM not initialized\n", getName());
7575 		PM_LOG1("[- %02x] %p [%p %s] !initialized\n",
7576 		    request->getType(), OBFUSCATE(request),
7577 		    OBFUSCATE(this), getName());
7578 
7579 		more = gIOPMCompletionQueue->queuePMRequest(request);
7580 		if (more) {
7581 			gIOPMWorkQueue->incrementProducerCount();
7582 		}
7583 	}
7584 
7585 	return more;
7586 }
7587 
7588 //*********************************************************************************
7589 // [private] actionPMCompletionQueue
7590 //
7591 // IOPMCompletionQueue::checkForWork() passing a completed request to the
7592 // request target.
7593 //*********************************************************************************
7594 
7595 bool
actionPMCompletionQueue(IOPMRequest * request,IOPMCompletionQueue * queue)7596 IOService::actionPMCompletionQueue(
7597 	IOPMRequest *         request,
7598 	IOPMCompletionQueue * queue )
7599 {
7600 	bool            more = (request->getNextRequest() != NULL);
7601 	IOPMRequest *   root = request->getRootRequest();
7602 
7603 	if (root && (root != request)) {
7604 		more = true;
7605 	}
7606 	if (more) {
7607 		gIOPMWorkQueue->incrementProducerCount();
7608 	}
7609 
7610 	releasePMRequest( request );
7611 	return more;
7612 }
7613 
7614 //*********************************************************************************
7615 // [private] actionPMWorkQueueRetire
7616 //
7617 // IOPMWorkQueue::checkForWork() passing a retired request to the request target.
7618 //*********************************************************************************
7619 
7620 bool
actionPMWorkQueueRetire(IOPMRequest * request,IOPMWorkQueue * queue)7621 IOService::actionPMWorkQueueRetire( IOPMRequest * request, IOPMWorkQueue * queue )
7622 {
7623 	assert(request && queue);
7624 
7625 	PM_LOG1("[- %02x] %p [%p %s] state %d, busy %d\n",
7626 	    request->getType(), OBFUSCATE(request),
7627 	    OBFUSCATE(this), getName(),
7628 	    fMachineState, gIOPMBusyRequestCount);
7629 
7630 	// Catch requests created by idleTimerExpired()
7631 	if (request->getType() == kIOPMRequestTypeActivityTickle) {
7632 		uint32_t tickleFlags = (uint32_t)(uintptr_t) request->fArg1;
7633 
7634 		if ((tickleFlags & kTickleTypePowerDrop) && fIdleTimerPeriod) {
7635 			restartIdleTimer();
7636 		} else if (tickleFlags == (kTickleTypeActivity | kTickleTypePowerRise)) {
7637 			// Invalidate any idle power drop that got queued while
7638 			// processing this request.
7639 			fIdleTimerGeneration++;
7640 		}
7641 	}
7642 
7643 	// When the completed request is linked, tell work queue there is
7644 	// more work pending.
7645 
7646 	return gIOPMCompletionQueue->queuePMRequest( request );
7647 }
7648 
7649 //*********************************************************************************
7650 // [private] isPMBlocked
7651 //
7652 // Check if machine state transition is blocked.
7653 //*********************************************************************************
7654 
7655 bool
isPMBlocked(IOPMRequest * request,int count)7656 IOService::isPMBlocked( IOPMRequest * request, int count )
7657 {
7658 	int reason = 0;
7659 
7660 	do {
7661 		if (kIOPM_Finished == fMachineState) {
7662 			break;
7663 		}
7664 
7665 		if (kIOPM_DriverThreadCallDone == fMachineState) {
7666 			// 5 = kDriverCallInformPreChange
7667 			// 6 = kDriverCallInformPostChange
7668 			// 7 = kDriverCallSetPowerState
7669 			// 8 = kRootDomainInformPreChange
7670 			if (fDriverCallBusy) {
7671 				reason = 5 + fDriverCallReason;
7672 			}
7673 			break;
7674 		}
7675 
7676 		// Waiting on driver's setPowerState() timeout.
7677 		if (fDriverTimer) {
7678 			reason = 1; break;
7679 		}
7680 
7681 		// Child or interested driver acks pending.
7682 		if (fHeadNotePendingAcks) {
7683 			reason = 2; break;
7684 		}
7685 
7686 		// Waiting on apps or priority power interest clients.
7687 		if (fResponseArray) {
7688 			reason = 3; break;
7689 		}
7690 
7691 #if USE_SETTLE_TIMER
7692 		// Waiting on settle timer expiration.
7693 		if (fSettleTimeUS) {
7694 			reason = 4; break;
7695 		}
7696 #endif
7697 	} while (false);
7698 
7699 	fWaitReason = reason;
7700 
7701 	if (reason) {
7702 		if (count) {
7703 			PM_LOG1("[B %02x] %p [%p %s] state %d, reason %d\n",
7704 			    request->getType(), OBFUSCATE(request),
7705 			    OBFUSCATE(this), getName(),
7706 			    fMachineState, reason);
7707 		}
7708 
7709 		return true;
7710 	}
7711 
7712 	return false;
7713 }
7714 
7715 //*********************************************************************************
7716 // [private] actionPMWorkQueueInvoke
7717 //
7718 // IOPMWorkQueue::checkForWork() passing a request to the
7719 // request target for execution.
7720 //*********************************************************************************
7721 
7722 bool
actionPMWorkQueueInvoke(IOPMRequest * request,IOPMWorkQueue * queue)7723 IOService::actionPMWorkQueueInvoke( IOPMRequest * request, IOPMWorkQueue * queue )
7724 {
7725 	bool    done = false;
7726 	int     loop = 0;
7727 
7728 	assert(request && queue);
7729 
7730 	while (isPMBlocked(request, loop++) == false) {
7731 		PM_LOG1("[W %02x] %p [%p %s] state %d\n",
7732 		    request->getType(), OBFUSCATE(request),
7733 		    OBFUSCATE(this), getName(), fMachineState);
7734 
7735 		gIOPMRequest = request;
7736 		gIOPMWorkInvokeCount++;
7737 
7738 		// Every PM machine states must be handled in one of the cases below.
7739 
7740 		switch (fMachineState) {
7741 		case kIOPM_Finished:
7742 			start_watchdog_timer();
7743 
7744 			executePMRequest( request );
7745 			break;
7746 
7747 		case kIOPM_OurChangeTellClientsPowerDown:
7748 			// Root domain might self cancel due to assertions.
7749 			if (IS_ROOT_DOMAIN) {
7750 				bool cancel = (bool) fDoNotPowerDown;
7751 				getPMRootDomain()->askChangeDownDone(
7752 					&fHeadNoteChangeFlags, &cancel);
7753 				fDoNotPowerDown = cancel;
7754 			}
7755 
7756 			// askChangeDown() done, was it vetoed?
7757 			if (!fDoNotPowerDown) {
7758 				// no, we can continue
7759 				OurChangeTellClientsPowerDown();
7760 			} else {
7761 				OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
7762 				PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
7763 				if (IS_ROOT_DOMAIN) {
7764 					// RootDomain already sent "WillSleep" to its clients
7765 					tellChangeUp(fCurrentPowerState);
7766 				} else {
7767 					tellNoChangeDown(fHeadNotePowerState);
7768 				}
7769 				// mark the change note un-actioned
7770 				fHeadNoteChangeFlags |= kIOPMNotDone;
7771 				// and we're done
7772 				OurChangeFinish();
7773 			}
7774 			break;
7775 
7776 		case kIOPM_OurChangeTellUserPMPolicyPowerDown:
7777 			// PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
7778 			if (fDoNotPowerDown) {
7779 				OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
7780 				PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
7781 				if (IS_ROOT_DOMAIN) {
7782 					// RootDomain already sent "WillSleep" to its clients
7783 					tellChangeUp(fCurrentPowerState);
7784 				} else {
7785 					tellNoChangeDown(fHeadNotePowerState);
7786 				}
7787 				// mark the change note un-actioned
7788 				fHeadNoteChangeFlags |= kIOPMNotDone;
7789 				// and we're done
7790 				OurChangeFinish();
7791 			} else {
7792 				OurChangeTellUserPMPolicyPowerDown();
7793 			}
7794 			break;
7795 
7796 		case kIOPM_OurChangeTellPriorityClientsPowerDown:
7797 			// PMRD:     LastCallBeforeSleep notify done
7798 			// Non-PMRD: tellChangeDown/kNotifyApps done
7799 			if (fDoNotPowerDown) {
7800 				OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
7801 				PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
7802 				// no, tell clients we're back in the old state
7803 				tellChangeUp(fCurrentPowerState);
7804 				// mark the change note un-actioned
7805 				fHeadNoteChangeFlags |= kIOPMNotDone;
7806 				// and we're done
7807 				OurChangeFinish();
7808 			} else {
7809 				// yes, we can continue
7810 				OurChangeTellPriorityClientsPowerDown();
7811 			}
7812 			break;
7813 
7814 		case kIOPM_OurChangeNotifyInterestedDriversWillChange:
7815 			OurChangeNotifyInterestedDriversWillChange();
7816 			break;
7817 
7818 		case kIOPM_OurChangeSetPowerState:
7819 			OurChangeSetPowerState();
7820 			break;
7821 
7822 		case kIOPM_OurChangeWaitForPowerSettle:
7823 			OurChangeWaitForPowerSettle();
7824 			break;
7825 
7826 		case kIOPM_OurChangeNotifyInterestedDriversDidChange:
7827 			OurChangeNotifyInterestedDriversDidChange();
7828 			break;
7829 
7830 		case kIOPM_OurChangeTellCapabilityDidChange:
7831 			OurChangeTellCapabilityDidChange();
7832 			break;
7833 
7834 		case kIOPM_OurChangeFinish:
7835 			OurChangeFinish();
7836 			break;
7837 
7838 		case kIOPM_ParentChangeTellPriorityClientsPowerDown:
7839 			ParentChangeTellPriorityClientsPowerDown();
7840 			break;
7841 
7842 		case kIOPM_ParentChangeNotifyInterestedDriversWillChange:
7843 			ParentChangeNotifyInterestedDriversWillChange();
7844 			break;
7845 
7846 		case kIOPM_ParentChangeSetPowerState:
7847 			ParentChangeSetPowerState();
7848 			break;
7849 
7850 		case kIOPM_ParentChangeWaitForPowerSettle:
7851 			ParentChangeWaitForPowerSettle();
7852 			break;
7853 
7854 		case kIOPM_ParentChangeNotifyInterestedDriversDidChange:
7855 			ParentChangeNotifyInterestedDriversDidChange();
7856 			break;
7857 
7858 		case kIOPM_ParentChangeTellCapabilityDidChange:
7859 			ParentChangeTellCapabilityDidChange();
7860 			break;
7861 
7862 		case kIOPM_ParentChangeAcknowledgePowerChange:
7863 			ParentChangeAcknowledgePowerChange();
7864 			break;
7865 
7866 		case kIOPM_DriverThreadCallDone:
7867 			switch (fDriverCallReason) {
7868 			case kDriverCallInformPreChange:
7869 			case kDriverCallInformPostChange:
7870 				notifyInterestedDriversDone();
7871 				break;
7872 			case kDriverCallSetPowerState:
7873 				notifyControllingDriverDone();
7874 				break;
7875 			case kRootDomainInformPreChange:
7876 				notifyRootDomainDone();
7877 				break;
7878 			default:
7879 				panic("%s: bad call reason %x",
7880 				    getName(), fDriverCallReason);
7881 			}
7882 			break;
7883 
7884 		case kIOPM_NotifyChildrenOrdered:
7885 			notifyChildrenOrdered();
7886 			break;
7887 
7888 		case kIOPM_NotifyChildrenDelayed:
7889 			notifyChildrenDelayed();
7890 			break;
7891 
7892 		case kIOPM_NotifyChildrenStart:
7893 			// pop notifyAll() state saved by notifyInterestedDriversDone()
7894 			MS_POP();
7895 			notifyRootDomain();
7896 			break;
7897 
7898 		case kIOPM_SyncTellClientsPowerDown:
7899 			// Root domain might self cancel due to assertions.
7900 			if (IS_ROOT_DOMAIN) {
7901 				bool cancel = (bool) fDoNotPowerDown;
7902 				getPMRootDomain()->askChangeDownDone(
7903 					&fHeadNoteChangeFlags, &cancel);
7904 				fDoNotPowerDown = cancel;
7905 			}
7906 			if (!fDoNotPowerDown) {
7907 				fMachineState = kIOPM_SyncTellPriorityClientsPowerDown;
7908 				fOutOfBandParameter = kNotifyApps;
7909 				tellChangeDown(fHeadNotePowerState);
7910 			} else {
7911 				// Cancelled by IOPMrootDomain::askChangeDownDone() or
7912 				// askChangeDown/kNotifyApps
7913 				OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
7914 				PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
7915 				tellNoChangeDown(fHeadNotePowerState);
7916 				fHeadNoteChangeFlags |= kIOPMNotDone;
7917 				OurChangeFinish();
7918 			}
7919 			break;
7920 
7921 		case kIOPM_SyncTellPriorityClientsPowerDown:
7922 			// PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
7923 			if (!fDoNotPowerDown) {
7924 				fMachineState = kIOPM_SyncNotifyWillChange;
7925 				fOutOfBandParameter = kNotifyPriority;
7926 				tellChangeDown(fHeadNotePowerState);
7927 			} else {
7928 				OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
7929 				PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
7930 				tellChangeUp(fCurrentPowerState);
7931 				fHeadNoteChangeFlags |= kIOPMNotDone;
7932 				OurChangeFinish();
7933 			}
7934 			break;
7935 
7936 		case kIOPM_SyncNotifyWillChange:
7937 			if (kIOPMSyncNoChildNotify & fHeadNoteChangeFlags) {
7938 				fMachineState = kIOPM_SyncFinish;
7939 				continue;
7940 			}
7941 			fMachineState     = kIOPM_SyncNotifyDidChange;
7942 			fDriverCallReason = kDriverCallInformPreChange;
7943 			notifyChildren();
7944 			break;
7945 
7946 		case kIOPM_SyncNotifyDidChange:
7947 			fIsPreChange = false;
7948 
7949 			if (fHeadNoteChangeFlags & kIOPMParentInitiated) {
7950 				fMachineState = kIOPM_SyncFinish;
7951 			} else {
7952 				assert(IS_ROOT_DOMAIN);
7953 				fMachineState = kIOPM_SyncTellCapabilityDidChange;
7954 			}
7955 
7956 			fDriverCallReason = kDriverCallInformPostChange;
7957 			notifyChildren();
7958 			break;
7959 
7960 		case kIOPM_SyncTellCapabilityDidChange:
7961 			tellSystemCapabilityChange( kIOPM_SyncFinish );
7962 			break;
7963 
7964 		case kIOPM_SyncFinish:
7965 			if (fHeadNoteChangeFlags & kIOPMParentInitiated) {
7966 				ParentChangeAcknowledgePowerChange();
7967 			} else {
7968 				OurChangeFinish();
7969 			}
7970 			break;
7971 
7972 		case kIOPM_TellCapabilityChangeDone:
7973 			if (fIsPreChange) {
7974 				if (fOutOfBandParameter == kNotifyCapabilityChangePriority) {
7975 					MS_POP(); // MS passed to tellSystemCapabilityChange()
7976 					continue;
7977 				}
7978 				fOutOfBandParameter = kNotifyCapabilityChangePriority;
7979 			} else {
7980 				if (fOutOfBandParameter == kNotifyCapabilityChangeApps) {
7981 					MS_POP(); // MS passed to tellSystemCapabilityChange()
7982 					continue;
7983 				}
7984 				fOutOfBandParameter = kNotifyCapabilityChangeApps;
7985 			}
7986 			tellClientsWithResponse( fOutOfBandMessage );
7987 			break;
7988 
7989 		default:
7990 			panic("PMWorkQueueInvoke: unknown machine state %x",
7991 			    fMachineState);
7992 		}
7993 
7994 		gIOPMRequest = NULL;
7995 
7996 		if (fMachineState == kIOPM_Finished) {
7997 			stop_watchdog_timer();
7998 			done = true;
7999 			break;
8000 		}
8001 	}
8002 
8003 	return done;
8004 }
8005 
8006 //*********************************************************************************
8007 // [private] executePMRequest
8008 //*********************************************************************************
8009 
8010 void
executePMRequest(IOPMRequest * request)8011 IOService::executePMRequest( IOPMRequest * request )
8012 {
8013 	assert( kIOPM_Finished == fMachineState );
8014 
8015 	switch (request->getType()) {
8016 	case kIOPMRequestTypePMStop:
8017 		handlePMstop( request );
8018 		break;
8019 
8020 	case kIOPMRequestTypeAddPowerChild1:
8021 		addPowerChild1( request );
8022 		break;
8023 
8024 	case kIOPMRequestTypeAddPowerChild2:
8025 		addPowerChild2( request );
8026 		break;
8027 
8028 	case kIOPMRequestTypeAddPowerChild3:
8029 		addPowerChild3( request );
8030 		break;
8031 
8032 	case kIOPMRequestTypeRegisterPowerDriver:
8033 		handleRegisterPowerDriver( request );
8034 		break;
8035 
8036 	case kIOPMRequestTypeAdjustPowerState:
8037 		fAdjustPowerScheduled = false;
8038 		adjustPowerState();
8039 		break;
8040 
8041 	case kIOPMRequestTypePowerDomainWillChange:
8042 		handlePowerDomainWillChangeTo( request );
8043 		break;
8044 
8045 	case kIOPMRequestTypePowerDomainDidChange:
8046 		handlePowerDomainDidChangeTo( request );
8047 		break;
8048 
8049 	case kIOPMRequestTypeRequestPowerState:
8050 	case kIOPMRequestTypeRequestPowerStateOverride:
8051 		handleRequestPowerState( request );
8052 		break;
8053 
8054 	case kIOPMRequestTypePowerOverrideOnPriv:
8055 	case kIOPMRequestTypePowerOverrideOffPriv:
8056 		handlePowerOverrideChanged( request );
8057 		break;
8058 
8059 	case kIOPMRequestTypeActivityTickle:
8060 		handleActivityTickle( request );
8061 		break;
8062 
8063 	case kIOPMRequestTypeSynchronizePowerTree:
8064 		handleSynchronizePowerTree( request );
8065 		break;
8066 
8067 	case kIOPMRequestTypeSetIdleTimerPeriod:
8068 	{
8069 		fIdleTimerPeriod = (typeof(fIdleTimerPeriod))(uintptr_t) request->fArg0;
8070 		fNextIdleTimerPeriod = fIdleTimerPeriod;
8071 		if ((false == fLockedFlags.PMStop) && (fIdleTimerPeriod > 0)) {
8072 			restartIdleTimer();
8073 		}
8074 	}
8075 	break;
8076 
8077 	case kIOPMRequestTypeIgnoreIdleTimer:
8078 		fIdleTimerIgnored = request->fArg0 ? 1 : 0;
8079 		break;
8080 
8081 	case kIOPMRequestTypeQuiescePowerTree:
8082 		gIOPMWorkQueue->finishQuiesceRequest(request);
8083 		break;
8084 
8085 	case kIOPMRequestTypeDeferredActivityTickle:
8086 		handleDeferredActivityTickle(request);
8087 		break;
8088 
8089 	default:
8090 		panic("executePMRequest: unknown request type %x", request->getType());
8091 	}
8092 }
8093 
8094 //*********************************************************************************
8095 // [private] actionPMReplyQueue
8096 //
8097 // IOPMRequestQueue::checkForWork() passing a reply-type request to the
8098 // request target.
8099 //*********************************************************************************
8100 
8101 bool
actionPMReplyQueue(IOPMRequest * request,IOPMRequestQueue * queue)8102 IOService::actionPMReplyQueue( IOPMRequest * request, IOPMRequestQueue * queue )
8103 {
8104 	bool more = false;
8105 
8106 	assert( request && queue );
8107 	assert( request->isReplyType());
8108 
8109 	PM_LOG1("[A %02x] %p [%p %s] state %d\n",
8110 	    request->getType(), OBFUSCATE(request),
8111 	    OBFUSCATE(this), getName(), fMachineState);
8112 
8113 	switch (request->getType()) {
8114 	case kIOPMRequestTypeAllowPowerChange:
8115 	case kIOPMRequestTypeCancelPowerChange:
8116 		// Check if we are expecting this response.
8117 		if (responseValid((uint32_t)(uintptr_t) request->fArg0,
8118 		    (int)(uintptr_t) request->fArg1)) {
8119 			if (kIOPMRequestTypeCancelPowerChange == request->getType()) {
8120 				// Clients are not allowed to cancel when kIOPMSkipAskPowerDown
8121 				// flag is set. Only root domain will set this flag.
8122 				// However, there is one exception to this rule. User-space PM
8123 				// policy may choose to cancel sleep even after all clients have
8124 				// been notified that we will lower power.
8125 
8126 				if ((fMachineState == kIOPM_OurChangeTellUserPMPolicyPowerDown)
8127 				    || (fMachineState == kIOPM_OurChangeTellPriorityClientsPowerDown)
8128 				    || ((fHeadNoteChangeFlags & kIOPMSkipAskPowerDown) == 0)) {
8129 					fDoNotPowerDown = true;
8130 
8131 					OSString * name = (OSString *) request->fArg2;
8132 					getPMRootDomain()->pmStatsRecordApplicationResponse(
8133 						gIOPMStatsResponseCancel,
8134 						name ? name->getCStringNoCopy() : "", 0,
8135 						0, (int)(uintptr_t) request->fArg1, NULL);
8136 				}
8137 			}
8138 
8139 			if (checkForDone()) {
8140 				stop_ack_timer();
8141 				cleanClientResponses(false);
8142 				more = true;
8143 			}
8144 		}
8145 		// OSString containing app name in Arg2 must be released.
8146 		if (request->getType() == kIOPMRequestTypeCancelPowerChange) {
8147 			OSObject * obj = (OSObject *) request->fArg2;
8148 			if (obj) {
8149 				obj->release();
8150 			}
8151 		}
8152 		break;
8153 
8154 	case kIOPMRequestTypeAckPowerChange:
8155 		more = handleAcknowledgePowerChange( request );
8156 		break;
8157 
8158 	case kIOPMRequestTypeAckSetPowerState:
8159 		more = handleAcknowledgeSetPowerState( request );
8160 		break;
8161 
8162 	case kIOPMRequestTypeInterestChanged:
8163 		handleInterestChanged( request );
8164 		more = true;
8165 		break;
8166 
8167 	case kIOPMRequestTypeIdleCancel:
8168 		if ((fMachineState == kIOPM_OurChangeTellClientsPowerDown)
8169 		    || (fMachineState == kIOPM_OurChangeTellUserPMPolicyPowerDown)
8170 		    || (fMachineState == kIOPM_OurChangeTellPriorityClientsPowerDown)
8171 		    || (fMachineState == kIOPM_SyncTellClientsPowerDown)
8172 		    || (fMachineState == kIOPM_SyncTellPriorityClientsPowerDown)) {
8173 			OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
8174 			PM_LOG2("%s: cancel from machine state %d\n",
8175 			    getName(), fMachineState);
8176 			fDoNotPowerDown = true;
8177 			// Stop waiting for app replys.
8178 			if ((fMachineState == kIOPM_OurChangeTellPriorityClientsPowerDown) ||
8179 			    (fMachineState == kIOPM_OurChangeTellUserPMPolicyPowerDown) ||
8180 			    (fMachineState == kIOPM_SyncTellPriorityClientsPowerDown) ||
8181 			    (fMachineState == kIOPM_SyncTellClientsPowerDown)) {
8182 				cleanClientResponses(false);
8183 			}
8184 			more = true;
8185 		}
8186 		break;
8187 
8188 	case kIOPMRequestTypeChildNotifyDelayCancel:
8189 		if (fMachineState == kIOPM_NotifyChildrenDelayed) {
8190 			PM_LOG2("%s: delay notify cancelled\n", getName());
8191 			notifyChildrenDelayed();
8192 		}
8193 		break;
8194 
8195 	default:
8196 		panic("PMReplyQueue: unknown reply type %x", request->getType());
8197 	}
8198 
8199 	more |= gIOPMCompletionQueue->queuePMRequest(request);
8200 	if (more) {
8201 		gIOPMWorkQueue->incrementProducerCount();
8202 	}
8203 
8204 	return more;
8205 }
8206 
8207 //*********************************************************************************
8208 // [private] assertPMDriverCall / deassertPMDriverCall
8209 //*********************************************************************************
8210 
8211 bool
assertPMDriverCall(IOPMDriverCallEntry * entry,IOOptionBits method,const IOPMinformee * inform,IOOptionBits options)8212 IOService::assertPMDriverCall(
8213 	IOPMDriverCallEntry *   entry,
8214 	IOOptionBits            method,
8215 	const IOPMinformee *    inform,
8216 	IOOptionBits            options )
8217 {
8218 	IOService * target = NULL;
8219 	bool        ok = false;
8220 
8221 	if (!initialized) {
8222 		return false;
8223 	}
8224 
8225 	PM_LOCK();
8226 
8227 	if (fLockedFlags.PMStop) {
8228 		goto fail;
8229 	}
8230 
8231 	if (((options & kIOPMDriverCallNoInactiveCheck) == 0) && isInactive()) {
8232 		goto fail;
8233 	}
8234 
8235 	if (inform) {
8236 		if (!inform->active) {
8237 			goto fail;
8238 		}
8239 		target = inform->whatObject;
8240 		if (target->isInactive()) {
8241 			goto fail;
8242 		}
8243 	}
8244 
8245 	// Record calling address for sleep failure diagnostics
8246 	switch (method) {
8247 	case kIOPMDriverCallMethodSetPowerState:
8248 		entry->callMethod = OSMemberFunctionCast(const void *, fControllingDriver, &IOService::setPowerState);
8249 		break;
8250 	case kIOPMDriverCallMethodWillChange:
8251 		entry->callMethod = OSMemberFunctionCast(const void *, target, &IOService::powerStateWillChangeTo);
8252 		break;
8253 	case kIOPMDriverCallMethodDidChange:
8254 		entry->callMethod = OSMemberFunctionCast(const void *, target, &IOService::powerStateDidChangeTo);
8255 		break;
8256 	case kIOPMDriverCallMethodUnknown:
8257 	case kIOPMDriverCallMethodSetAggressive:
8258 	default:
8259 		entry->callMethod = NULL;
8260 		break;
8261 	}
8262 
8263 	entry->thread = current_thread();
8264 	entry->target = target;
8265 	queue_enter(&fPMDriverCallQueue, entry, IOPMDriverCallEntry *, link);
8266 	ok = true;
8267 
8268 fail:
8269 	PM_UNLOCK();
8270 
8271 	return ok;
8272 }
8273 
8274 void
deassertPMDriverCall(IOPMDriverCallEntry * entry)8275 IOService::deassertPMDriverCall( IOPMDriverCallEntry * entry )
8276 {
8277 	bool wakeup = false;
8278 
8279 	PM_LOCK();
8280 
8281 	assert( !queue_empty(&fPMDriverCallQueue));
8282 	queue_remove(&fPMDriverCallQueue, entry, IOPMDriverCallEntry *, link);
8283 	if (fLockedFlags.PMDriverCallWait) {
8284 		wakeup = true;
8285 	}
8286 
8287 	PM_UNLOCK();
8288 
8289 	if (wakeup) {
8290 		PM_LOCK_WAKEUP(&fPMDriverCallQueue);
8291 	}
8292 }
8293 
8294 bool
getBlockingDriverCall(thread_t * thread,const void ** callMethod)8295 IOService::getBlockingDriverCall(thread_t *thread, const void **callMethod)
8296 {
8297 	const IOPMDriverCallEntry * entry = NULL;
8298 	bool    blocked = false;
8299 
8300 	if (!initialized) {
8301 		return false;
8302 	}
8303 
8304 	if (current_thread() != gIOPMWatchDogThread) {
8305 		// Meant to be accessed only from watchdog thread
8306 		return false;
8307 	}
8308 
8309 	PM_LOCK();
8310 	entry = qe_queue_first(&fPMDriverCallQueue, IOPMDriverCallEntry, link);
8311 	if (entry) {
8312 		*thread = entry->thread;
8313 		*callMethod = entry->callMethod;
8314 		blocked = true;
8315 	}
8316 	PM_UNLOCK();
8317 
8318 	return blocked;
8319 }
8320 
8321 
8322 void
waitForPMDriverCall(IOService * target)8323 IOService::waitForPMDriverCall( IOService * target )
8324 {
8325 	const IOPMDriverCallEntry * entry;
8326 	thread_t                    thread = current_thread();
8327 	AbsoluteTime                deadline;
8328 	int                         waitResult;
8329 	bool                        log = true;
8330 	bool                        wait;
8331 
8332 	do {
8333 		wait = false;
8334 		queue_iterate(&fPMDriverCallQueue, entry, const IOPMDriverCallEntry *, link)
8335 		{
8336 			// Target of interested driver call
8337 			if (target && (target != entry->target)) {
8338 				continue;
8339 			}
8340 
8341 			if (entry->thread == thread) {
8342 				if (log) {
8343 					PM_LOG("%s: %s(%s) on PM thread\n",
8344 					    fName, __FUNCTION__, target ? target->getName() : "");
8345 					OSReportWithBacktrace("%s: %s(%s) on PM thread\n",
8346 					    fName, __FUNCTION__, target ? target->getName() : "");
8347 					log = false;
8348 				}
8349 				continue;
8350 			}
8351 
8352 			wait = true;
8353 			break;
8354 		}
8355 
8356 		if (wait) {
8357 			fLockedFlags.PMDriverCallWait = true;
8358 			clock_interval_to_deadline(15, kSecondScale, &deadline);
8359 			waitResult = PM_LOCK_SLEEP(&fPMDriverCallQueue, deadline);
8360 			fLockedFlags.PMDriverCallWait = false;
8361 			if (THREAD_TIMED_OUT == waitResult) {
8362 				PM_ERROR("%s: waitForPMDriverCall timeout\n", fName);
8363 				wait = false;
8364 			}
8365 		}
8366 	} while (wait);
8367 }
8368 
8369 //*********************************************************************************
8370 // [private] Debug helpers
8371 //*********************************************************************************
8372 
8373 const char *
getIOMessageString(uint32_t msg)8374 IOService::getIOMessageString( uint32_t msg )
8375 {
8376 #define MSG_ENTRY(x)    {(int) x, #x}
8377 
8378 	static const IONamedValue msgNames[] = {
8379 		MSG_ENTRY( kIOMessageCanDevicePowerOff      ),
8380 		MSG_ENTRY( kIOMessageDeviceWillPowerOff     ),
8381 		MSG_ENTRY( kIOMessageDeviceWillNotPowerOff  ),
8382 		MSG_ENTRY( kIOMessageDeviceHasPoweredOn     ),
8383 		MSG_ENTRY( kIOMessageCanSystemPowerOff      ),
8384 		MSG_ENTRY( kIOMessageSystemWillPowerOff     ),
8385 		MSG_ENTRY( kIOMessageSystemWillNotPowerOff  ),
8386 		MSG_ENTRY( kIOMessageCanSystemSleep         ),
8387 		MSG_ENTRY( kIOMessageSystemWillSleep        ),
8388 		MSG_ENTRY( kIOMessageSystemWillNotSleep     ),
8389 		MSG_ENTRY( kIOMessageSystemHasPoweredOn     ),
8390 		MSG_ENTRY( kIOMessageSystemWillRestart      ),
8391 		MSG_ENTRY( kIOMessageSystemWillPowerOn      ),
8392 		MSG_ENTRY( kIOMessageSystemCapabilityChange ),
8393 		MSG_ENTRY( kIOPMMessageLastCallBeforeSleep  ),
8394 		MSG_ENTRY( kIOMessageSystemPagingOff        ),
8395 		{ 0, NULL }
8396 	};
8397 
8398 	return IOFindNameForValue(msg, msgNames);
8399 }
8400 
8401 static const char *
getNotificationPhaseString(uint32_t phase)8402 getNotificationPhaseString( uint32_t phase )
8403 {
8404 #define PHASE_ENTRY(x)    {(int) x, #x}
8405 
8406 	static const IONamedValue phaseNames[] = {
8407 		PHASE_ENTRY( kNotifyApps                     ),
8408 		PHASE_ENTRY( kNotifyPriority                 ),
8409 		PHASE_ENTRY( kNotifyCapabilityChangeApps     ),
8410 		PHASE_ENTRY( kNotifyCapabilityChangePriority ),
8411 		{ 0, NULL }
8412 	};
8413 
8414 	return IOFindNameForValue(phase, phaseNames);
8415 }
8416 
8417 // MARK: -
8418 // MARK: IOPMRequest
8419 
8420 //*********************************************************************************
8421 // IOPMRequest Class
8422 //
8423 // Requests from PM clients, and also used for inter-object messaging within PM.
8424 //*********************************************************************************
8425 
8426 OSDefineMetaClassAndStructors( IOPMRequest, IOCommand );
8427 
8428 IOPMRequest *
create(void)8429 IOPMRequest::create( void )
8430 {
8431 	IOPMRequest * me = OSTypeAlloc(IOPMRequest);
8432 	if (me && !me->init(NULL, kIOPMRequestTypeInvalid)) {
8433 		me->release();
8434 		me = NULL;
8435 	}
8436 	return me;
8437 }
8438 
8439 bool
init(IOService * target,IOOptionBits type)8440 IOPMRequest::init( IOService * target, IOOptionBits type )
8441 {
8442 	if (!IOCommand::init()) {
8443 		return false;
8444 	}
8445 
8446 	fRequestType = type;
8447 	fTarget = target;
8448 
8449 	if (fTarget) {
8450 		fTarget->retain();
8451 	}
8452 
8453 	// Root node and root domain requests does not prevent the power tree from
8454 	// becoming quiescent.
8455 
8456 	fIsQuiesceBlocker = ((fTarget != gIOPMRootNode) &&
8457 	    (fTarget != IOService::getPMRootDomain()));
8458 
8459 	return true;
8460 }
8461 
8462 void
reset(void)8463 IOPMRequest::reset( void )
8464 {
8465 	assert( fWorkWaitCount == 0 );
8466 	assert( fFreeWaitCount == 0 );
8467 
8468 	detachNextRequest();
8469 	detachRootRequest();
8470 
8471 	if (fCompletionAction && (fRequestType == kIOPMRequestTypeQuiescePowerTree)) {
8472 		// Call the completion on PM work loop context
8473 		fCompletionAction(fCompletionTarget, fCompletionParam);
8474 		fCompletionAction = NULL;
8475 	}
8476 
8477 	fRequestType = kIOPMRequestTypeInvalid;
8478 
8479 	if (fTarget) {
8480 		fTarget->release();
8481 		fTarget = NULL;
8482 	}
8483 }
8484 
8485 bool
attachNextRequest(IOPMRequest * next)8486 IOPMRequest::attachNextRequest( IOPMRequest * next )
8487 {
8488 	bool ok = false;
8489 
8490 	if (!fRequestNext) {
8491 		// Postpone the execution of the next request after
8492 		// this request.
8493 		fRequestNext = next;
8494 		fRequestNext->fWorkWaitCount++;
8495 #if LOG_REQUEST_ATTACH
8496 		PM_LOG("Attached next: %p [0x%x] -> %p [0x%x, %u] %s\n",
8497 		    OBFUSCATE(this), fRequestType, OBFUSCATE(fRequestNext),
8498 		    fRequestNext->fRequestType,
8499 		    (uint32_t) fRequestNext->fWorkWaitCount,
8500 		    fTarget->getName());
8501 #endif
8502 		ok = true;
8503 	}
8504 	return ok;
8505 }
8506 
8507 bool
detachNextRequest(void)8508 IOPMRequest::detachNextRequest( void )
8509 {
8510 	bool ok = false;
8511 
8512 	if (fRequestNext) {
8513 		assert(fRequestNext->fWorkWaitCount);
8514 		if (fRequestNext->fWorkWaitCount) {
8515 			fRequestNext->fWorkWaitCount--;
8516 		}
8517 #if LOG_REQUEST_ATTACH
8518 		PM_LOG("Detached next: %p [0x%x] -> %p [0x%x, %u] %s\n",
8519 		    OBFUSCATE(this), fRequestType, OBFUSCATE(fRequestNext),
8520 		    fRequestNext->fRequestType,
8521 		    (uint32_t) fRequestNext->fWorkWaitCount,
8522 		    fTarget->getName());
8523 #endif
8524 		fRequestNext = NULL;
8525 		ok = true;
8526 	}
8527 	return ok;
8528 }
8529 
8530 bool
attachRootRequest(IOPMRequest * root)8531 IOPMRequest::attachRootRequest( IOPMRequest * root )
8532 {
8533 	bool ok = false;
8534 
8535 	if (!fRequestRoot) {
8536 		// Delay the completion of the root request after
8537 		// this request.
8538 		fRequestRoot = root;
8539 		fRequestRoot->fFreeWaitCount++;
8540 #if LOG_REQUEST_ATTACH
8541 		PM_LOG("Attached root: %p [0x%x] -> %p [0x%x, %u] %s\n",
8542 		    OBFUSCATE(this), (uint32_t) fType, OBFUSCATE(fRequestRoot),
8543 		    (uint32_t) fRequestRoot->fType,
8544 		    (uint32_t) fRequestRoot->fFreeWaitCount,
8545 		    fTarget->getName());
8546 #endif
8547 		ok = true;
8548 	}
8549 	return ok;
8550 }
8551 
8552 bool
detachRootRequest(void)8553 IOPMRequest::detachRootRequest( void )
8554 {
8555 	bool ok = false;
8556 
8557 	if (fRequestRoot) {
8558 		assert(fRequestRoot->fFreeWaitCount);
8559 		if (fRequestRoot->fFreeWaitCount) {
8560 			fRequestRoot->fFreeWaitCount--;
8561 		}
8562 #if LOG_REQUEST_ATTACH
8563 		PM_LOG("Detached root: %p [0x%x] -> %p [0x%x, %u] %s\n",
8564 		    OBFUSCATE(this), (uint32_t) fType, OBFUSCATE(fRequestRoot),
8565 		    (uint32_t) fRequestRoot->fType,
8566 		    (uint32_t) fRequestRoot->fFreeWaitCount,
8567 		    fTarget->getName());
8568 #endif
8569 		fRequestRoot = NULL;
8570 		ok = true;
8571 	}
8572 	return ok;
8573 }
8574 
8575 // MARK: -
8576 // MARK: IOPMRequestQueue
8577 
8578 //*********************************************************************************
8579 // IOPMRequestQueue Class
8580 //
8581 // Global queues. Queues are created once and never released.
8582 //*********************************************************************************
8583 
8584 OSDefineMetaClassAndStructors( IOPMRequestQueue, IOEventSource );
8585 
8586 IOPMRequestQueue *
create(IOService * inOwner,Action inAction)8587 IOPMRequestQueue::create( IOService * inOwner, Action inAction )
8588 {
8589 	IOPMRequestQueue * me = OSTypeAlloc(IOPMRequestQueue);
8590 	if (me && !me->init(inOwner, inAction)) {
8591 		me->release();
8592 		me = NULL;
8593 	}
8594 	return me;
8595 }
8596 
8597 bool
init(IOService * inOwner,Action inAction)8598 IOPMRequestQueue::init( IOService * inOwner, Action inAction )
8599 {
8600 	if (!inAction || !IOEventSource::init(inOwner, (IOEventSourceAction)inAction)) {
8601 		return false;
8602 	}
8603 
8604 	queue_init(&fQueue);
8605 	fLock = IOLockAlloc();
8606 	return fLock != NULL;
8607 }
8608 
8609 void
free(void)8610 IOPMRequestQueue::free( void )
8611 {
8612 	if (fLock) {
8613 		IOLockFree(fLock);
8614 		fLock = NULL;
8615 	}
8616 	return IOEventSource::free();
8617 }
8618 
8619 void
queuePMRequest(IOPMRequest * request)8620 IOPMRequestQueue::queuePMRequest( IOPMRequest * request )
8621 {
8622 	uint64_t now = mach_continuous_time();
8623 
8624 	assert(request);
8625 	request->setTimestamp(now);
8626 	IOLockLock(fLock);
8627 	queue_enter(&fQueue, request, typeof(request), fCommandChain);
8628 	IOLockUnlock(fLock);
8629 	if (workLoop) {
8630 		signalWorkAvailable();
8631 	}
8632 }
8633 
8634 void
queuePMRequestChain(IOPMRequest ** requests,IOItemCount count)8635 IOPMRequestQueue::queuePMRequestChain( IOPMRequest ** requests, IOItemCount count )
8636 {
8637 	IOPMRequest * next;
8638 	uint64_t now = mach_continuous_time();
8639 
8640 	assert(requests && count);
8641 	IOLockLock(fLock);
8642 	while (count--) {
8643 		next = *requests;
8644 		next->setTimestamp(now);
8645 		requests++;
8646 		queue_enter(&fQueue, next, typeof(next), fCommandChain);
8647 	}
8648 	IOLockUnlock(fLock);
8649 	if (workLoop) {
8650 		signalWorkAvailable();
8651 	}
8652 }
8653 
8654 bool
checkForWork(void)8655 IOPMRequestQueue::checkForWork( void )
8656 {
8657 	Action          dqAction = (Action) action;
8658 	IOPMRequest *   request;
8659 	IOService *     target;
8660 	int             dequeueCount = 0;
8661 	bool            more = false;
8662 
8663 	IOLockLock( fLock );
8664 
8665 	while (!queue_empty(&fQueue)) {
8666 		if (dequeueCount++ >= kMaxDequeueCount) {
8667 			// Allow other queues a chance to work
8668 			more = true;
8669 			break;
8670 		}
8671 
8672 		queue_remove_first(&fQueue, request, typeof(request), fCommandChain);
8673 		IOLockUnlock(fLock);
8674 		target = request->getTarget();
8675 		assert(target);
8676 		more |= (*dqAction)( target, request, this );
8677 		IOLockLock( fLock );
8678 	}
8679 
8680 	IOLockUnlock( fLock );
8681 	return more;
8682 }
8683 
8684 // MARK: -
8685 // MARK: IOPMWorkQueue
8686 
8687 //*********************************************************************************
8688 // IOPMWorkQueue Class
8689 //
8690 // Queue of IOServicePM objects, each with a queue of IOPMRequest sharing the
8691 // same target.
8692 //*********************************************************************************
8693 
8694 OSDefineMetaClassAndStructors( IOPMWorkQueue, IOEventSource );
8695 
8696 IOPMWorkQueue *
create(IOService * inOwner,Action invoke,Action retire)8697 IOPMWorkQueue::create( IOService * inOwner, Action invoke, Action retire )
8698 {
8699 	IOPMWorkQueue * me = OSTypeAlloc(IOPMWorkQueue);
8700 	if (me && !me->init(inOwner, invoke, retire)) {
8701 		me->release();
8702 		me = NULL;
8703 	}
8704 	return me;
8705 }
8706 
8707 bool
init(IOService * inOwner,Action invoke,Action retire)8708 IOPMWorkQueue::init( IOService * inOwner, Action invoke, Action retire )
8709 {
8710 	if (!invoke || !retire ||
8711 	    !IOEventSource::init(inOwner, (IOEventSourceAction)NULL)) {
8712 		return false;
8713 	}
8714 
8715 	queue_init(&fWorkQueue);
8716 
8717 	fInvokeAction  = invoke;
8718 	fRetireAction  = retire;
8719 	fConsumerCount = fProducerCount = 0;
8720 
8721 	return true;
8722 }
8723 
8724 bool
queuePMRequest(IOPMRequest * request,IOServicePM * pwrMgt)8725 IOPMWorkQueue::queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt )
8726 {
8727 	queue_head_t *  requestQueue;
8728 	bool            more  = false;
8729 	bool            empty;
8730 
8731 	assert( request );
8732 	assert( pwrMgt );
8733 	assert( onThread());
8734 	assert( queue_next(&request->fCommandChain) ==
8735 	    queue_prev(&request->fCommandChain));
8736 
8737 	gIOPMBusyRequestCount++;
8738 
8739 	if (request->isQuiesceType()) {
8740 		if ((request->getTarget() == gIOPMRootNode) && !fQuiesceStartTime) {
8741 			// Attach new quiesce request to all quiesce blockers in the queue
8742 			fQuiesceStartTime = mach_absolute_time();
8743 			attachQuiesceRequest(request);
8744 			fQuiesceRequest = request;
8745 		}
8746 	} else if (fQuiesceRequest && request->isQuiesceBlocker()) {
8747 		// Attach the new quiesce blocker to the blocked quiesce request
8748 		request->attachNextRequest(fQuiesceRequest);
8749 	}
8750 
8751 	// Add new request to the tail of the per-service request queue.
8752 	// Then immediately check the request queue to minimize latency
8753 	// if the queue was empty.
8754 
8755 	requestQueue = &pwrMgt->RequestHead;
8756 	empty = queue_empty(requestQueue);
8757 	queue_enter(requestQueue, request, typeof(request), fCommandChain);
8758 	if (empty) {
8759 		more = checkRequestQueue(requestQueue, &empty);
8760 		if (!empty) {
8761 			// Request just added is blocked, add its target IOServicePM
8762 			// to the work queue.
8763 			assert( queue_next(&pwrMgt->WorkChain) ==
8764 			    queue_prev(&pwrMgt->WorkChain));
8765 
8766 			queue_enter(&fWorkQueue, pwrMgt, typeof(pwrMgt), WorkChain);
8767 			fQueueLength++;
8768 			PM_LOG3("IOPMWorkQueue: [%u] added %s@%p to queue\n",
8769 			    fQueueLength, pwrMgt->Name, OBFUSCATE(pwrMgt));
8770 		}
8771 	}
8772 
8773 	return more;
8774 }
8775 
8776 bool
checkRequestQueue(queue_head_t * requestQueue,bool * empty)8777 IOPMWorkQueue::checkRequestQueue( queue_head_t * requestQueue, bool * empty )
8778 {
8779 	IOPMRequest *   request;
8780 	IOService *     target;
8781 	bool            more = false;
8782 	bool            done = false;
8783 
8784 	assert(!queue_empty(requestQueue));
8785 	do {
8786 		request = (typeof(request))queue_first(requestQueue);
8787 		if (request->isWorkBlocked()) {
8788 			break; // request dispatch blocked on attached request
8789 		}
8790 		target = request->getTarget();
8791 		if (fInvokeAction) {
8792 			done = (*fInvokeAction)( target, request, this );
8793 		} else {
8794 			PM_LOG("PM request 0x%x dropped\n", request->getType());
8795 			done = true;
8796 		}
8797 		if (!done) {
8798 			break; // PM state machine blocked
8799 		}
8800 		assert(gIOPMBusyRequestCount > 0);
8801 		if (gIOPMBusyRequestCount) {
8802 			gIOPMBusyRequestCount--;
8803 		}
8804 
8805 		if (request == fQuiesceRequest) {
8806 			fQuiesceRequest = NULL;
8807 		}
8808 
8809 		queue_remove_first(requestQueue, request, typeof(request), fCommandChain);
8810 		more |= (*fRetireAction)( target, request, this );
8811 		done = queue_empty(requestQueue);
8812 	} while (!done);
8813 
8814 	*empty = done;
8815 
8816 	if (more) {
8817 		// Retired a request that may unblock a previously visited request
8818 		// that is still waiting on the work queue. Must trigger another
8819 		// queue check.
8820 		fProducerCount++;
8821 	}
8822 
8823 	return more;
8824 }
8825 
8826 bool
checkForWork(void)8827 IOPMWorkQueue::checkForWork( void )
8828 {
8829 	IOServicePM *   entry;
8830 	IOServicePM *   next;
8831 	bool            more = false;
8832 	bool            empty;
8833 
8834 #if WORK_QUEUE_STATS
8835 	fStatCheckForWork++;
8836 #endif
8837 
8838 	// Iterate over all IOServicePM entries in the work queue,
8839 	// and check each entry's request queue.
8840 
8841 	while (fConsumerCount != fProducerCount) {
8842 		PM_LOG3("IOPMWorkQueue: checkForWork %u %u\n",
8843 		    fProducerCount, fConsumerCount);
8844 
8845 		fConsumerCount = fProducerCount;
8846 
8847 #if WORK_QUEUE_STATS
8848 		if (queue_empty(&fWorkQueue)) {
8849 			fStatQueueEmpty++;
8850 			break;
8851 		}
8852 		fStatScanEntries++;
8853 		uint32_t cachedWorkCount = gIOPMWorkInvokeCount;
8854 #endif
8855 
8856 		__IGNORE_WCASTALIGN(entry = (typeof(entry))queue_first(&fWorkQueue));
8857 		while (!queue_end(&fWorkQueue, (queue_entry_t) entry)) {
8858 			more |= checkRequestQueue(&entry->RequestHead, &empty);
8859 
8860 			// Get next entry, points to head if current entry is last.
8861 			__IGNORE_WCASTALIGN(next = (typeof(next))queue_next(&entry->WorkChain));
8862 
8863 			// if request queue is empty, remove IOServicePM from work queue.
8864 			if (empty) {
8865 				assert(fQueueLength);
8866 				if (fQueueLength) {
8867 					fQueueLength--;
8868 				}
8869 				PM_LOG3("IOPMWorkQueue: [%u] removed %s@%p from queue\n",
8870 				    fQueueLength, entry->Name, OBFUSCATE(entry));
8871 				queue_remove(&fWorkQueue, entry, typeof(entry), WorkChain);
8872 			}
8873 			entry = next;
8874 		}
8875 
8876 #if WORK_QUEUE_STATS
8877 		if (cachedWorkCount == gIOPMWorkInvokeCount) {
8878 			fStatNoWorkDone++;
8879 		}
8880 #endif
8881 	}
8882 
8883 	return more;
8884 }
8885 
8886 void
signalWorkAvailable(void)8887 IOPMWorkQueue::signalWorkAvailable( void )
8888 {
8889 	fProducerCount++;
8890 	IOEventSource::signalWorkAvailable();
8891 }
8892 
8893 void
incrementProducerCount(void)8894 IOPMWorkQueue::incrementProducerCount( void )
8895 {
8896 	fProducerCount++;
8897 }
8898 
8899 void
attachQuiesceRequest(IOPMRequest * quiesceRequest)8900 IOPMWorkQueue::attachQuiesceRequest( IOPMRequest * quiesceRequest )
8901 {
8902 	IOServicePM *   entry;
8903 	IOPMRequest *   request;
8904 
8905 	if (queue_empty(&fWorkQueue)) {
8906 		return;
8907 	}
8908 
8909 	queue_iterate(&fWorkQueue, entry, typeof(entry), WorkChain)
8910 	{
8911 		queue_iterate(&entry->RequestHead, request, typeof(request), fCommandChain)
8912 		{
8913 			// Attach the quiesce request to any request in the queue that
8914 			// is not linked to a next request. These requests will block
8915 			// the quiesce request.
8916 
8917 			if (request->isQuiesceBlocker()) {
8918 				request->attachNextRequest(quiesceRequest);
8919 			}
8920 		}
8921 	}
8922 }
8923 
8924 void
finishQuiesceRequest(IOPMRequest * quiesceRequest)8925 IOPMWorkQueue::finishQuiesceRequest( IOPMRequest * quiesceRequest )
8926 {
8927 	if (fQuiesceRequest && (quiesceRequest == fQuiesceRequest) &&
8928 	    (fQuiesceStartTime != 0)) {
8929 		fInvokeAction = NULL;
8930 		fQuiesceFinishTime = mach_absolute_time();
8931 	}
8932 }
8933 
8934 // MARK: -
8935 // MARK: IOPMCompletionQueue
8936 
8937 //*********************************************************************************
8938 // IOPMCompletionQueue Class
8939 //*********************************************************************************
8940 
8941 OSDefineMetaClassAndStructors( IOPMCompletionQueue, IOEventSource );
8942 
8943 IOPMCompletionQueue *
create(IOService * inOwner,Action inAction)8944 IOPMCompletionQueue::create( IOService * inOwner, Action inAction )
8945 {
8946 	IOPMCompletionQueue * me = OSTypeAlloc(IOPMCompletionQueue);
8947 	if (me && !me->init(inOwner, inAction)) {
8948 		me->release();
8949 		me = NULL;
8950 	}
8951 	return me;
8952 }
8953 
8954 bool
init(IOService * inOwner,Action inAction)8955 IOPMCompletionQueue::init( IOService * inOwner, Action inAction )
8956 {
8957 	if (!inAction || !IOEventSource::init(inOwner, (IOEventSourceAction)inAction)) {
8958 		return false;
8959 	}
8960 
8961 	queue_init(&fQueue);
8962 	return true;
8963 }
8964 
8965 bool
queuePMRequest(IOPMRequest * request)8966 IOPMCompletionQueue::queuePMRequest( IOPMRequest * request )
8967 {
8968 	bool more;
8969 
8970 	assert(request);
8971 	// unblock dependent request
8972 	more = request->detachNextRequest();
8973 	queue_enter(&fQueue, request, typeof(request), fCommandChain);
8974 	return more;
8975 }
8976 
8977 bool
checkForWork(void)8978 IOPMCompletionQueue::checkForWork( void )
8979 {
8980 	Action          dqAction = (Action) action;
8981 	IOPMRequest *   request;
8982 	IOPMRequest *   next;
8983 	IOService *     target;
8984 	bool            more = false;
8985 
8986 	request = (typeof(request))queue_first(&fQueue);
8987 	while (!queue_end(&fQueue, (queue_entry_t) request)) {
8988 		next = (typeof(next))queue_next(&request->fCommandChain);
8989 		if (!request->isFreeBlocked()) {
8990 			queue_remove(&fQueue, request, typeof(request), fCommandChain);
8991 			target = request->getTarget();
8992 			assert(target);
8993 			more |= (*dqAction)( target, request, this );
8994 		}
8995 		request = next;
8996 	}
8997 
8998 	return more;
8999 }
9000 
9001 // MARK: -
9002 // MARK: IOServicePM
9003 
OSDefineMetaClassAndStructors(IOServicePM,OSObject)9004 OSDefineMetaClassAndStructors(IOServicePM, OSObject)
9005 
9006 //*********************************************************************************
9007 // serialize
9008 //
9009 // Serialize IOServicePM for debugging.
9010 //*********************************************************************************
9011 
9012 static void
9013 setPMProperty( OSDictionary * dict, const char * key, uint64_t value )
9014 {
9015 	OSNumber * num = OSNumber::withNumber(value, sizeof(value) * 8);
9016 	if (num) {
9017 		dict->setObject(key, num);
9018 		num->release();
9019 	}
9020 }
9021 
9022 IOReturn
gatedSerialize(OSSerialize * s) const9023 IOServicePM::gatedSerialize( OSSerialize * s  ) const
9024 {
9025 	OSDictionary *  dict;
9026 	bool            ok = false;
9027 	int             powerClamp = -1;
9028 	int             dictSize = 6;
9029 
9030 	if (IdleTimerPeriod) {
9031 		dictSize += 4;
9032 	}
9033 
9034 	if (PMActions.state & kPMActionsStatePowerClamped) {
9035 		dictSize += 1;
9036 		powerClamp = 0;
9037 		if (PMActions.flags &
9038 		    (kPMActionsFlagIsDisplayWrangler | kPMActionsFlagIsGraphicsDriver)) {
9039 			powerClamp++;
9040 		}
9041 	}
9042 
9043 #if WORK_QUEUE_STATS
9044 	if (gIOPMRootNode == ControllingDriver) {
9045 		dictSize += 4;
9046 	}
9047 #endif
9048 
9049 	if (PowerClients) {
9050 		dict = OSDictionary::withDictionary(
9051 			PowerClients, PowerClients->getCount() + dictSize);
9052 	} else {
9053 		dict = OSDictionary::withCapacity(dictSize);
9054 	}
9055 
9056 	if (dict) {
9057 		setPMProperty(dict, "CurrentPowerState", CurrentPowerState);
9058 		setPMProperty(dict, "CapabilityFlags", CurrentCapabilityFlags);
9059 		if (NumberOfPowerStates) {
9060 			setPMProperty(dict, "MaxPowerState", NumberOfPowerStates - 1);
9061 		}
9062 		if (DesiredPowerState != CurrentPowerState) {
9063 			setPMProperty(dict, "DesiredPowerState", DesiredPowerState);
9064 		}
9065 		if (kIOPM_Finished != MachineState) {
9066 			setPMProperty(dict, "MachineState", MachineState);
9067 		}
9068 		if (DeviceOverrideEnabled) {
9069 			dict->setObject("PowerOverrideOn", kOSBooleanTrue);
9070 		}
9071 		if (powerClamp >= 0) {
9072 			setPMProperty(dict, "PowerClamp", powerClamp);
9073 		}
9074 
9075 		if (IdleTimerPeriod) {
9076 			AbsoluteTime    now;
9077 			AbsoluteTime    delta;
9078 			uint64_t        nsecs;
9079 
9080 			clock_get_uptime(&now);
9081 
9082 			// The idle timer period in milliseconds
9083 			setPMProperty(dict, "IdleTimerPeriod", NextIdleTimerPeriod * 1000ULL);
9084 
9085 			// Number of tickles since the last idle timer expiration
9086 			setPMProperty(dict, "ActivityTickles", ActivityTickleCount);
9087 
9088 			if (AbsoluteTime_to_scalar(&DeviceActiveTimestamp)) {
9089 				// Milliseconds since the last activity tickle
9090 				delta = now;
9091 				SUB_ABSOLUTETIME(&delta, &DeviceActiveTimestamp);
9092 				absolutetime_to_nanoseconds(delta, &nsecs);
9093 				setPMProperty(dict, "TimeSinceLastTickle", NS_TO_MS(nsecs));
9094 			}
9095 
9096 			if (!IdleTimerStopped && AbsoluteTime_to_scalar(&IdleTimerStartTime)) {
9097 				// Idle timer elapsed time in milliseconds
9098 				delta = now;
9099 				SUB_ABSOLUTETIME(&delta, &IdleTimerStartTime);
9100 				absolutetime_to_nanoseconds(delta, &nsecs);
9101 				setPMProperty(dict, "IdleTimerElapsedTime", NS_TO_MS(nsecs));
9102 			}
9103 		}
9104 
9105 #if WORK_QUEUE_STATS
9106 		if (gIOPMRootNode == Owner) {
9107 			setPMProperty(dict, "WQ-CheckForWork",
9108 			    gIOPMWorkQueue->fStatCheckForWork);
9109 			setPMProperty(dict, "WQ-ScanEntries",
9110 			    gIOPMWorkQueue->fStatScanEntries);
9111 			setPMProperty(dict, "WQ-QueueEmpty",
9112 			    gIOPMWorkQueue->fStatQueueEmpty);
9113 			setPMProperty(dict, "WQ-NoWorkDone",
9114 			    gIOPMWorkQueue->fStatNoWorkDone);
9115 		}
9116 #endif
9117 
9118 		if (HasAdvisoryDesire && !gIOPMAdvisoryTickleEnabled) {
9119 			// Don't report advisory tickle when it has no influence
9120 			dict->removeObject(gIOPMPowerClientAdvisoryTickle);
9121 		}
9122 
9123 		ok = dict->serialize(s);
9124 		dict->release();
9125 	}
9126 
9127 	return ok ? kIOReturnSuccess : kIOReturnNoMemory;
9128 }
9129 
9130 bool
serialize(OSSerialize * s) const9131 IOServicePM::serialize( OSSerialize * s ) const
9132 {
9133 	IOReturn ret = kIOReturnNotReady;
9134 
9135 	if (gIOPMWatchDogThread == current_thread()) {
9136 		// Calling without lock as this data is collected for debug purpose, before reboot.
9137 		// The workloop is probably already hung in state machine.
9138 		ret = gatedSerialize(s);
9139 	} else if (gIOPMWorkLoop) {
9140 		ret = gIOPMWorkLoop->runAction(
9141 			OSMemberFunctionCast(IOWorkLoop::Action, this, &IOServicePM::gatedSerialize),
9142 			(OSObject *) this, (void *) s);
9143 	}
9144 
9145 	return kIOReturnSuccess == ret;
9146 }
9147 
9148 void
pmPrint(uint32_t event,uintptr_t param1,uintptr_t param2) const9149 IOServicePM::pmPrint(
9150 	uint32_t        event,
9151 	uintptr_t       param1,
9152 	uintptr_t       param2 ) const
9153 {
9154 	gPlatform->PMLog(Name, event, param1, param2);
9155 }
9156 
9157 void
pmTrace(uint32_t event,uint32_t eventFunc,uintptr_t param1,uintptr_t param2) const9158 IOServicePM::pmTrace(
9159 	uint32_t        event,
9160 	uint32_t        eventFunc,
9161 	uintptr_t       param1,
9162 	uintptr_t       param2 ) const
9163 {
9164 	uintptr_t nameAsArg = 0;
9165 
9166 	assert(event < KDBG_CODE_MAX);
9167 	assert((eventFunc & ~KDBG_FUNC_MASK) == 0);
9168 
9169 	// Copy the first characters of the name into an uintptr_t.
9170 	// NULL termination is not required.
9171 	strncpy((char*)&nameAsArg, Name, sizeof(nameAsArg));
9172 
9173 #if defined(XNU_TARGET_OS_OSX)
9174 	KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, IODBG_POWER(event) | eventFunc, nameAsArg,
9175 	    (uintptr_t)Owner->getRegistryEntryID(), (uintptr_t)(OBFUSCATE(param1)),
9176 	    (uintptr_t)(OBFUSCATE(param2)), 0);
9177 #else
9178 	IOTimeStampConstant(IODBG_POWER(event) | eventFunc, nameAsArg, (uintptr_t)Owner->getRegistryEntryID(), (uintptr_t)(OBFUSCATE(param1)), (uintptr_t)(OBFUSCATE(param2)));
9179 #endif
9180 }
9181