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