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