]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOServicePMPrivate.h
xnu-2422.90.20.tar.gz
[apple/xnu.git] / iokit / Kernel / IOServicePMPrivate.h
1 /*
2 * Copyright (c) 2007 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 #ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30 #define _IOKIT_IOSERVICEPMPRIVATE_H
31
32 #include <IOKit/IOCommand.h>
33 #include <IOKit/IOEventSource.h>
34
35 //******************************************************************************
36 // PM command types
37 //******************************************************************************
38
39 enum {
40 /* Command Types */
41 kIOPMRequestTypeInvalid = 0x00,
42 kIOPMRequestTypePMStop = 0x01,
43 kIOPMRequestTypeAddPowerChild1 = 0x02,
44 kIOPMRequestTypeAddPowerChild2 = 0x03,
45 kIOPMRequestTypeAddPowerChild3 = 0x04,
46 kIOPMRequestTypeRegisterPowerDriver = 0x05,
47 kIOPMRequestTypeAdjustPowerState = 0x06,
48 kIOPMRequestTypePowerDomainWillChange = 0x07,
49 kIOPMRequestTypePowerDomainDidChange = 0x08,
50 kIOPMRequestTypePowerOverrideOnPriv = 0x09,
51 kIOPMRequestTypePowerOverrideOffPriv = 0x0A,
52 kIOPMRequestTypeActivityTickle = 0x0B,
53 kIOPMRequestTypeRequestPowerState = 0x0C,
54 kIOPMRequestTypeSynchronizePowerTree = 0x0D,
55 kIOPMRequestTypeRequestPowerStateOverride = 0x0E,
56 kIOPMRequestTypeSetIdleTimerPeriod = 0x0F,
57 kIOPMRequestTypeIgnoreIdleTimer = 0x10,
58
59 /* Reply Types */
60 kIOPMRequestTypeReplyStart = 0x80,
61 kIOPMRequestTypeAckPowerChange = 0x81,
62 kIOPMRequestTypeAckSetPowerState = 0x82,
63 kIOPMRequestTypeAllowPowerChange = 0x83,
64 kIOPMRequestTypeCancelPowerChange = 0x84,
65 kIOPMRequestTypeInterestChanged = 0x85,
66 kIOPMRequestTypeIdleCancel = 0x86,
67 kIOPMRequestTypeChildNotifyDelayCancel = 0x87
68 };
69
70 //******************************************************************************
71 // PM actions - For root domain only
72 //******************************************************************************
73
74 struct IOPMActions;
75
76 typedef void
77 (*IOPMActionPowerChangeStart)(
78 void * target,
79 IOService * service,
80 IOPMActions * actions,
81 IOPMPowerStateIndex powerState,
82 IOPMPowerChangeFlags * changeFlags,
83 IOPMRequestTag requestTag );
84
85 typedef void
86 (*IOPMActionPowerChangeDone)(
87 void * target,
88 IOService * service,
89 IOPMActions * actions,
90 IOPMPowerStateIndex powerState,
91 IOPMPowerChangeFlags changeFlags,
92 IOPMRequestTag requestTag );
93
94 typedef void
95 (*IOPMActionPowerChangeOverride)(
96 void * target,
97 IOService * service,
98 IOPMActions * actions,
99 IOPMPowerStateIndex * powerState,
100 IOPMPowerChangeFlags * changeFlags,
101 IOPMRequestTag requestTag );
102
103 typedef void
104 (*IOPMActionActivityTickle)(
105 void * target,
106 IOService * service,
107 IOPMActions * actions );
108
109 typedef void
110 (*IOPMActionUpdatePowerClient)(
111 void * target,
112 IOService * service,
113 IOPMActions * actions,
114 const OSSymbol * powerClient,
115 IOPMPowerStateIndex oldPowerState,
116 IOPMPowerStateIndex newPowerState
117 );
118
119 struct IOPMActions {
120 void * target;
121 uint32_t parameter;
122 IOPMActionPowerChangeStart actionPowerChangeStart;
123 IOPMActionPowerChangeDone actionPowerChangeDone;
124 IOPMActionPowerChangeOverride actionPowerChangeOverride;
125 IOPMActionActivityTickle actionActivityTickle;
126 IOPMActionUpdatePowerClient actionUpdatePowerClient;
127 };
128
129 // IOPMActions parameter flags
130 enum {
131 kPMActionsFlagIsDisplayWrangler = 0x00000100,
132 kPMActionsFlagIsGraphicsDevice = 0x00000200,
133 kPMActionsFlagIsAudioDevice = 0x00000400,
134 kPMActionsFlagLimitPower = 0x00000800,
135 kPMActionsPCIBitNumberMask = 0x000000ff
136 };
137
138 //******************************************************************************
139
140 enum {
141 kIOPMEventClassSystemEvent = 0x00,
142 kIOPMEventClassDriverEvent = 0x1
143 };
144
145 class PMEventDetails : public OSObject
146 {
147 OSDeclareDefaultStructors( PMEventDetails );
148 friend class IOServicePM;
149 friend class IOPMrootDomain;
150 friend class IOPMTimeline;
151 public:
152 static PMEventDetails *eventDetails(uint32_t type,
153 const char *ownerName,
154 uintptr_t ownerUnique,
155 const char *interestName,
156 uint8_t oldState,
157 uint8_t newState,
158 uint32_t result,
159 uint32_t elapsedTimeUS);
160
161 static PMEventDetails *eventDetails(uint32_t type,
162 const char *uuid,
163 uint32_t reason,
164 uint32_t result);
165 private:
166 uint8_t eventClassifier;
167 uint32_t eventType;
168 const char *ownerName;
169 uintptr_t ownerUnique;
170 const char *interestName;
171 uint8_t oldState;
172 uint8_t newState;
173 uint32_t result;
174 uint32_t elapsedTimeUS;
175
176 const char *uuid;
177 uint32_t reason;
178 };
179
180 // Internal concise representation of IOPMPowerState
181 struct IOPMPSEntry
182 {
183 IOPMPowerFlags capabilityFlags;
184 IOPMPowerFlags outputPowerFlags;
185 IOPMPowerFlags inputPowerFlags;
186 uint32_t staticPower;
187 uint32_t settleUpTime;
188 uint32_t settleDownTime;
189 IOPMPowerStateIndex stateOrder;
190 IOPMPowerStateIndex stateOrderToIndex;
191 };
192
193 //******************************************************************************
194 // IOServicePM
195 //******************************************************************************
196
197 class IOServicePM : public OSObject
198 {
199 friend class IOService;
200 friend class IOPMWorkQueue;
201
202 OSDeclareDefaultStructors( IOServicePM )
203
204 private:
205 // Link IOServicePM objects on IOPMWorkQueue.
206 queue_chain_t WorkChain;
207
208 // Queue of IOPMRequest objects.
209 queue_head_t RequestHead;
210
211 // IOService creator and owner.
212 IOService * Owner;
213
214 // List of interested drivers (protected by PMLock).
215 IOPMinformeeList * InterestedDrivers;
216
217 // How long to wait for controlling driver to acknowledge.
218 IOReturn DriverTimer;
219
220 // Current power management machine state.
221 uint32_t MachineState;
222
223 thread_call_t AckTimer;
224 thread_call_t SettleTimer;
225 thread_call_t IdleTimer;
226 thread_call_t WatchdogTimer;
227
228 // Settle time after changing power state.
229 uint32_t SettleTimeUS;
230
231 // The flags describing current change note.
232 IOPMPowerChangeFlags HeadNoteChangeFlags;
233
234 // The new power state number being changed to.
235 IOPMPowerStateIndex HeadNotePowerState;
236
237 // Points to the entry in the power state array.
238 IOPMPSEntry * HeadNotePowerArrayEntry;
239
240 // Power flags supplied by all parents (domain).
241 IOPMPowerFlags HeadNoteDomainFlags;
242
243 // Power flags supplied by domain accounting for parent changes.
244 IOPMPowerFlags HeadNoteDomainTargetFlags;
245
246 // Connection attached to the changing parent.
247 IOPowerConnection * HeadNoteParentConnection;
248
249 // Power flags supplied by the changing parent.
250 IOPMPowerFlags HeadNoteParentFlags;
251
252 // Number of acks still outstanding.
253 uint32_t HeadNotePendingAcks;
254
255 // PM state lock.
256 IOLock * PMLock;
257
258 unsigned int InitialPowerChange :1;
259 unsigned int InitialSetPowerState :1;
260 unsigned int DeviceOverrideEnabled :1;
261 unsigned int DoNotPowerDown :1;
262 unsigned int ParentsKnowState :1;
263 unsigned int StrictTreeOrder :1;
264 unsigned int IdleTimerStopped :1;
265 unsigned int AdjustPowerScheduled :1;
266
267 unsigned int IsPreChange :1;
268 unsigned int DriverCallBusy :1;
269 unsigned int PCDFunctionOverride :1;
270 unsigned int IdleTimerIgnored :1;
271 unsigned int HasAdvisoryDesire :1;
272 unsigned int AdvisoryTickleUsed :1;
273 unsigned int ResetPowerStateOnWake :1;
274
275 // Time of last device activity.
276 AbsoluteTime DeviceActiveTimestamp;
277
278 // Used to protect activity flag.
279 IOLock * ActivityLock;
280
281 // Idle timer's period in seconds.
282 unsigned long IdleTimerPeriod;
283 unsigned long IdleTimerMinPowerState;
284 AbsoluteTime IdleTimerStartTime;
285
286 // Power state desired by a subclassed device object.
287 IOPMPowerStateIndex DeviceDesire;
288
289 // This is the power state we desire currently.
290 IOPMPowerStateIndex DesiredPowerState;
291
292 // This is what our parent thinks our need is.
293 IOPMPowerFlags PreviousRequestPowerFlags;
294
295 // Cache result from getName(), used in logging.
296 const char * Name;
297
298 // Number of power states in the power array.
299 IOPMPowerStateIndex NumberOfPowerStates;
300
301 // Ordered highest power state in the power array.
302 IOPMPowerStateIndex HighestPowerState;
303
304 // Power state array.
305 IOPMPSEntry * PowerStates;
306
307 // The controlling driver.
308 IOService * ControllingDriver;
309
310 // Our current power state.
311 IOPMPowerStateIndex CurrentPowerState;
312
313 // Logical OR of power flags for each power domain parent.
314 IOPMPowerFlags ParentsCurrentPowerFlags;
315
316 // The highest power state we can achieve in current power domain.
317 IOPMPowerStateIndex MaxPowerState;
318
319 // Logical OR of all output power flags in the power state array.
320 IOPMPowerFlags MergedOutputPowerFlags;
321
322 // OSArray which manages responses from notified apps and clients.
323 OSArray * ResponseArray;
324 OSArray * NotifyClientArray;
325
326 // Used to uniquely identify power management notification to apps and clients.
327 UInt16 SerialNumber;
328
329 // Used to communicate desired function to tellClientsWithResponse().
330 // This is used because it avoids changing the signatures of the affected virtual methods.
331 int OutOfBandParameter;
332
333 AbsoluteTime DriverCallStartTime;
334 IOPMPowerFlags CurrentCapabilityFlags;
335 unsigned long CurrentPowerConsumption;
336 IOPMPowerStateIndex TempClampPowerState;
337 OSArray * NotifyChildArray;
338 OSDictionary * PowerClients;
339 thread_call_t DriverCallEntry;
340 void * DriverCallParamPtr;
341 IOItemCount DriverCallParamCount;
342 IOItemCount DriverCallParamSlots;
343 uint32_t DriverCallReason;
344 uint32_t OutOfBandMessage;
345 uint32_t TempClampCount;
346 uint32_t OverrideMaxPowerState;
347 uint32_t DeviceUsablePowerState;
348
349 // Protected by ActivityLock - BEGIN
350 IOPMPowerStateIndex ActivityTicklePowerState;
351 IOPMPowerStateIndex AdvisoryTicklePowerState;
352 uint32_t ActivityTickleCount;
353 uint32_t DeviceWasActive : 1;
354 uint32_t AdvisoryTickled : 1;
355 // Protected by ActivityLock - END
356
357 uint32_t WaitReason;
358 uint32_t SavedMachineState;
359 uint32_t RootDomainState;
360
361 // Protected by PMLock - BEGIN
362 struct {
363 uint32_t PMStop : 1;
364 uint32_t PMDriverCallWait : 1;
365 } LockedFlags;
366
367 queue_head_t PMDriverCallQueue;
368 OSSet * InsertInterestSet;
369 OSSet * RemoveInterestSet;
370
371
372 // IOReporter Data
373 uint32_t ReportClientCnt;
374 void * ReportBuf;
375 // Protected by PMLock - END
376
377
378 #if PM_VARS_SUPPORT
379 IOPMprot * PMVars;
380 #endif
381
382 IOPMActions PMActions;
383
384 // Serialize IOServicePM state for debug output.
385 IOReturn gatedSerialize( OSSerialize * s ) const;
386 virtual bool serialize( OSSerialize * s ) const;
387
388 // PM log and trace
389 void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
390 void pmTrace( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
391 };
392
393 #define fOwner pwrMgt->Owner
394 #define fInterestedDrivers pwrMgt->InterestedDrivers
395 #define fDriverTimer pwrMgt->DriverTimer
396 #define fMachineState pwrMgt->MachineState
397 #define fAckTimer pwrMgt->AckTimer
398 #define fSettleTimer pwrMgt->SettleTimer
399 #define fIdleTimer pwrMgt->IdleTimer
400 #define fWatchdogTimer pwrMgt->WatchdogTimer
401 #define fSettleTimeUS pwrMgt->SettleTimeUS
402 #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags
403 #define fHeadNotePowerState pwrMgt->HeadNotePowerState
404 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry
405 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags
406 #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags
407 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection
408 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags
409 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
410 #define fPMLock pwrMgt->PMLock
411 #define fInitialPowerChange pwrMgt->InitialPowerChange
412 #define fInitialSetPowerState pwrMgt->InitialSetPowerState
413 #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled
414 #define fDoNotPowerDown pwrMgt->DoNotPowerDown
415 #define fParentsKnowState pwrMgt->ParentsKnowState
416 #define fStrictTreeOrder pwrMgt->StrictTreeOrder
417 #define fIdleTimerStopped pwrMgt->IdleTimerStopped
418 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled
419 #define fIsPreChange pwrMgt->IsPreChange
420 #define fDriverCallBusy pwrMgt->DriverCallBusy
421 #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride
422 #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored
423 #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire
424 #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed
425 #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake
426 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
427 #define fActivityLock pwrMgt->ActivityLock
428 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
429 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState
430 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime
431 #define fDeviceDesire pwrMgt->DeviceDesire
432 #define fDesiredPowerState pwrMgt->DesiredPowerState
433 #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags
434 #define fName pwrMgt->Name
435 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
436 #define fHighestPowerState pwrMgt->HighestPowerState
437 #define fPowerStates pwrMgt->PowerStates
438 #define fControllingDriver pwrMgt->ControllingDriver
439 #define fCurrentPowerState pwrMgt->CurrentPowerState
440 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
441 #define fMaxPowerState pwrMgt->MaxPowerState
442 #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags
443 #define fResponseArray pwrMgt->ResponseArray
444 #define fNotifyClientArray pwrMgt->NotifyClientArray
445 #define fSerialNumber pwrMgt->SerialNumber
446 #define fOutOfBandParameter pwrMgt->OutOfBandParameter
447 #define fDriverCallStartTime pwrMgt->DriverCallStartTime
448 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
449 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
450 #define fTempClampPowerState pwrMgt->TempClampPowerState
451 #define fNotifyChildArray pwrMgt->NotifyChildArray
452 #define fPowerClients pwrMgt->PowerClients
453 #define fDriverCallEntry pwrMgt->DriverCallEntry
454 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
455 #define fDriverCallParamCount pwrMgt->DriverCallParamCount
456 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
457 #define fDriverCallReason pwrMgt->DriverCallReason
458 #define fOutOfBandMessage pwrMgt->OutOfBandMessage
459 #define fTempClampCount pwrMgt->TempClampCount
460 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState
461 #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState
462 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
463 #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState
464 #define fActivityTickleCount pwrMgt->ActivityTickleCount
465 #define fDeviceWasActive pwrMgt->DeviceWasActive
466 #define fAdvisoryTickled pwrMgt->AdvisoryTickled
467 #define fWaitReason pwrMgt->WaitReason
468 #define fSavedMachineState pwrMgt->SavedMachineState
469 #define fRootDomainState pwrMgt->RootDomainState
470 #define fLockedFlags pwrMgt->LockedFlags
471 #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue
472 #define fInsertInterestSet pwrMgt->InsertInterestSet
473 #define fRemoveInterestSet pwrMgt->RemoveInterestSet
474 #define fReportClientCnt pwrMgt->ReportClientCnt
475 #define fReportBuf pwrMgt->ReportBuf
476 #define fPMVars pwrMgt->PMVars
477 #define fPMActions pwrMgt->PMActions
478
479 #define StateOrder(state) (((state) < fNumberOfPowerStates) \
480 ? pwrMgt->PowerStates[(state)].stateOrder \
481 : (state))
482 #define StateMax(a,b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a))
483 #define StateMin(a,b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b))
484
485 #define kPowerStateZero (0)
486
487 /*
488 When an IOService is waiting for acknowledgement to a power change
489 notification from an interested driver or the controlling driver,
490 the ack timer is ticking every tenth of a second.
491 (100000000 nanoseconds are one tenth of a second).
492 */
493 #define ACK_TIMER_PERIOD 100000000
494
495 #define WATCHDOG_TIMER_PERIOD (300) // 300 secs
496
497 // Max wait time in microseconds for kernel priority and capability clients
498 // with async message handlers to acknowledge.
499 //
500 #define kPriorityClientMaxWait (90 * 1000 * 1000)
501 #define kCapabilityClientMaxWait (240 * 1000 * 1000)
502
503 // Attributes describing a power state change.
504 // See IOPMPowerChangeFlags data type.
505 //
506 #define kIOPMParentInitiated 0x0001 // power change initiated by our parent
507 #define kIOPMSelfInitiated 0x0002 // power change initiated by this device
508 #define kIOPMNotDone 0x0004 // we couldn't make this change
509 #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo
510 #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo
511 #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power
512 #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires
513 #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase
514 #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync
515 #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree
516 #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages
517 #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake
518 #define kIOPMInitialPowerChange 0x1000 // set for initial power change
519 #define kIOPMRootChangeUp 0x2000 // Root power domain change up
520 #define kIOPMRootChangeDown 0x4000 // Root power domain change down
521 #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration
522
523 #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \
524 kIOPMRootChangeUp | kIOPMRootChangeDown)
525
526 // Activity tickle request flags
527 #define kTickleTypePowerDrop 0x01
528 #define kTickleTypePowerRise 0x02
529 #define kTickleTypeActivity 0x04
530 #define kTickleTypeAdvisory 0x08
531
532 enum {
533 kDriverCallInformPreChange,
534 kDriverCallInformPostChange,
535 kDriverCallSetPowerState,
536 kRootDomainInformPreChange
537 };
538
539 struct DriverCallParam {
540 OSObject * Target;
541 IOReturn Result;
542 };
543
544 // values of OutOfBandParameter
545 enum {
546 kNotifyApps,
547 kNotifyPriority,
548 kNotifyCapabilityChangeApps,
549 kNotifyCapabilityChangePriority
550 };
551
552 typedef bool (*IOPMMessageFilter)(
553 void * target, void * object, void * arg1, void * arg2, void * arg3 );
554
555 // used for applyToInterested
556 struct IOPMInterestContext {
557 OSArray * responseArray;
558 OSArray * notifyClients;
559 uint16_t serialNumber;
560 uint8_t isPreChange;
561 uint8_t enableTracing;
562 uint32_t maxTimeRequested;
563 uint32_t messageType;
564 uint32_t notifyType;
565 IOService * us;
566 IOPMPowerStateIndex stateNumber;
567 IOPMPowerFlags stateFlags;
568 IOPMPowerChangeFlags changeFlags;
569 const char * errorLog;
570 IOPMMessageFilter messageFilter;
571 };
572
573 // assertPMDriverCall() options
574 enum {
575 kIOPMADC_NoInactiveCheck = 1
576 };
577
578 //******************************************************************************
579 // PM Statistics & Diagnostics
580 //******************************************************************************
581
582 extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut;
583 extern const OSSymbol *gIOPMStatsApplicationResponseCancel;
584 extern const OSSymbol *gIOPMStatsApplicationResponseSlow;
585
586 //******************************************************************************
587 // IOPMRequest
588 //******************************************************************************
589
590 typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status);
591
592 class IOPMRequest : public IOCommand
593 {
594 OSDeclareDefaultStructors( IOPMRequest )
595
596 protected:
597 IOService * fTarget; // request target
598 IOPMRequest * fRequestNext; // the next request in the chain
599 IOPMRequest * fRequestRoot; // the root request in the issue tree
600 IOItemCount fWorkWaitCount; // execution blocked if non-zero
601 IOItemCount fFreeWaitCount; // completion blocked if non-zero
602 uint32_t fType; // request type
603
604 #if NOT_READY
605 IOPMCompletionAction fCompletionAction;
606 void * fCompletionTarget;
607 void * fCompletionParam;
608 IOReturn fCompletionStatus;
609 #endif
610
611 public:
612 uint32_t fRequestTag;
613 void * fArg0;
614 void * fArg1;
615 void * fArg2;
616
617 inline bool isWorkBlocked( void ) const
618 {
619 return (fWorkWaitCount != 0);
620 }
621
622 inline bool isFreeBlocked( void ) const
623 {
624 return (fFreeWaitCount != 0);
625 }
626
627 inline IOPMRequest * getNextRequest( void ) const
628 {
629 return fRequestNext;
630 }
631
632 inline IOPMRequest * getRootRequest( void ) const
633 {
634 if (fRequestRoot) return fRequestRoot;
635 #if NOT_READY
636 if (fCompletionAction) return (IOPMRequest *) this;
637 #endif
638 return 0;
639 }
640
641 inline uint32_t getType( void ) const
642 {
643 return fType;
644 }
645
646 inline bool isReplyType( void ) const
647 {
648 return (fType > kIOPMRequestTypeReplyStart);
649 }
650
651 inline IOService * getTarget( void ) const
652 {
653 return fTarget;
654 }
655
656 #if NOT_READY
657 inline bool isCompletionInstalled( void )
658 {
659 return (fCompletionAction != 0);
660 }
661
662 inline void installCompletionAction(
663 IOPMCompletionAction action,
664 void * target,
665 void * param )
666 {
667 fCompletionAction = action;
668 fCompletionTarget = target;
669 fCompletionParam = param;
670 }
671 #endif /* NOT_READY */
672
673 static IOPMRequest * create( void );
674 bool init( IOService * owner, IOOptionBits type );
675 void reset( void );
676 bool attachNextRequest( IOPMRequest * next );
677 bool detachNextRequest( void );
678 bool attachRootRequest( IOPMRequest * root );
679 bool detachRootRequest( void );
680 };
681
682 //******************************************************************************
683 // IOPMRequestQueue
684 //******************************************************************************
685
686 class IOPMRequestQueue : public IOEventSource
687 {
688 OSDeclareDefaultStructors( IOPMRequestQueue )
689
690 public:
691 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
692
693 protected:
694 queue_head_t fQueue;
695 IOLock * fLock;
696
697 virtual bool checkForWork( void );
698 virtual void free( void );
699 virtual bool init( IOService * inOwner, Action inAction );
700
701 public:
702 static IOPMRequestQueue * create( IOService * inOwner, Action inAction );
703 void queuePMRequest( IOPMRequest * request );
704 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
705 };
706
707 //******************************************************************************
708 // IOPMWorkQueue
709 //******************************************************************************
710
711 #define WORK_QUEUE_STATS 1
712
713 class IOPMWorkQueue : public IOEventSource
714 {
715 OSDeclareDefaultStructors( IOPMWorkQueue )
716
717 public:
718 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
719
720 #if WORK_QUEUE_STATS
721 uint64_t fStatCheckForWork;
722 uint64_t fStatScanEntries;
723 uint64_t fStatQueueEmpty;
724 uint64_t fStatNoWorkDone;
725 #endif
726
727 protected:
728 queue_head_t fWorkQueue;
729 Action fWorkAction;
730 Action fRetireAction;
731 uint32_t fQueueLength;
732 uint32_t fConsumerCount;
733 volatile uint32_t fProducerCount;
734
735 virtual bool checkForWork( void );
736 virtual bool init( IOService * inOwner, Action work, Action retire );
737 bool checkRequestQueue( queue_head_t * queue, bool * empty );
738
739 public:
740 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
741 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
742 void signalWorkAvailable( void );
743 void incrementProducerCount( void );
744 };
745
746 //******************************************************************************
747 // IOPMCompletionQueue
748 //******************************************************************************
749
750 class IOPMCompletionQueue : public IOEventSource
751 {
752 OSDeclareDefaultStructors( IOPMCompletionQueue )
753
754 public:
755 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
756
757 protected:
758 queue_head_t fQueue;
759
760 virtual bool checkForWork( void );
761 virtual bool init( IOService * inOwner, Action inAction );
762
763 public:
764 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
765 bool queuePMRequest( IOPMRequest * request );
766 };
767
768 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */