/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ extern "C" { #include <kern/thread_call.h> } #include <libkern/c++/OSObject.h> #include <IOKit/IOLocks.h> class IOPMinformee; class IOPMinformeeList; class IOPMchangeNoteList; class IOPMpmChild; class IOWorkLoop; class IOCommandQueue; class IOCommandGate; class IOTimerEventSource; class IOPlatformExpert; #include <IOKit/pwr_mgt/IOPM.h> /*! @defined ACK_TIMER_PERIOD @discussion When an IOService is waiting for acknowledgement to a power state change notification from an interested driver or the controlling driver its ack timer is ticking every tenth of a second. (100000000 nanoseconds are one tenth of a second). */ #define ACK_TIMER_PERIOD 100000000 /*! @class IOPMpriv @abstract Private power management private instance variables for IOService objects. */ class IOPMpriv : public OSObject { friend class IOService; OSDeclareDefaultStructors(IOPMpriv) public: /*! @var we_are_root TRUE if this device is the root power domain. */ bool we_are_root; /*! @var interestedDrivers List of interested drivers. */ IOPMinformeeList * interestedDrivers; /*! @var children List of power domain children. */ IOPMinformeeList * children; /*! @var changeList List of pending power state changes. */ IOPMchangeNoteList * changeList; /*! @var driver_timer Timeout on waiting for controlling driver to acknowledgeSetPowerState. */ IOReturn driver_timer; /*! @var ackTimer */ thread_call_t ackTimer; /*! @var settleTimer */ thread_call_t settleTimer; /*! @var machine_state State number of state machine processing current change note. */ unsigned long machine_state; /*! @var settle_time Settle timer after changing power state. */ unsigned long settle_time; /*! @var head_note Ordinal of change note currently being processed. */ long head_note; /*! @var head_note_flags Copy of flags field in change note currently being processed. */ unsigned long head_note_flags; /*! @var head_note_state Copy of newStateNumberfield in change note currently being processed. */ unsigned long head_note_state; /*! @var head_note_outputFlags OutputPowerCharacter field from change note currently being processed. */ unsigned long head_note_outputFlags; /*! @var head_note_domainState Power domain flags from parent... (only on parent change). */ unsigned long head_note_domainState; /*! @var head_note_parent Pointer to initiating parent... (only on parent change). */ IOPowerConnection * head_note_parent; /*! @var head_note_capabilityFlags Copy of capabilityFlags field in change note currently being processed. */ unsigned long head_note_capabilityFlags; /*! @var head_note_pendingAcks Number of acks we are waiting for during notification. */ unsigned long head_note_pendingAcks; /*! @var our_lock Used to control access to head_note_pendingAcks and driver_timer. */ IOLock * our_lock; /*! @var flags_lock Used to control access to response flags array. */ IOLock * flags_lock; /*! @var queue_lock Used to control access to change note queue. */ IOLock * queue_lock; /*! @var initial_change True forces first state to be broadcast even if it isn't a change. */ bool initial_change; /*! @var need_to_become_usable Someone called makeUsable before we had a controlling driver. */ bool need_to_become_usable; /*! @var device_overrides State changes are made based only on subclass's desire. */ bool device_overrides; /*! @var clampOn Domain is clamped on till first child registers. */ bool clampOn; /*! @var owner Points to object which made this struct. Used for debug output only. */ IOService * owner; /*! @var activityLock Used to protect activity flag. */ IOLock * activityLock; /*! @var timerEventSrc An idle timer. */ IOTimerEventSource * timerEventSrc; /*! @var idle_timer_period Timer's period in seconds. */ unsigned long idle_timer_period; /*! @var clampTimerEventSrc Timer for clamping power on. */ IOTimerEventSource * clampTimerEventSrc; /*! @var device_active True: there has been device activity since last idle timer expiration. */ bool device_active; /*! @var device_active_timestamp Time in ticks of last activity. */ AbsoluteTime device_active_timestamp; /*! @var driverDesire This is the power state desired by our controlling driver. It is initialized to myCurrentState and is changed when the controlling driver calls changePowerStateTo. A change in driverDesire may cause a change in ourDesiredPowerState. */ unsigned long driverDesire; /*! @var deviceDesire This is the power state desired by a subclassed device object. It is initialized to myCurrentState and is changed when the subclassed object calls changePowerStateToPriv. A change in deviceDesire may cause a change in ourDesiredPowerState. */ unsigned long deviceDesire; /*! @var ourDesiredPowerState This is the power state we desire currently. If equal to myCurrentState, we're happy. Otherwise, we're waiting for the parent to raise the power domain to at least this level. If this is a power domain, this is the maximum of all our children's desires, driverDesire, and deviceDesire. It increases when: a child asks for more power via requestDomainState, the controlling driver asks for more power via changePowerStateTo It decreases when: we lose a child and the child had the highest power need of all our children, the child with the highest power need suggests a lower power domain state, the controlling driver asks for lower power for some reason via changePowerStateTo If this is not a power domain, ourDesiredPowerState represents the greater of driverDesire and deviceDesire. It increases when: the controlling driver asks for more power via changePowerStateTo some driver calls makeUsable a subclassed object asks for more power via changePowerStateToPriv It decreases when: the controlling driver asks for lower power for some reason via changePowerStateTo a subclassed object asks for lower power for some reason via changePowerStateToPriv */ unsigned long ourDesiredPowerState; /*! @var previousRequest This is a reminder of what our parent thinks our need is. Whenever it changes, we call requestDomainState in the parent to keep it current. It is usually equal to ourDesiredPowerState except while a power change is in progress. */ unsigned long previousRequest; /*! @var askingFor Not used. */ unsigned long askingFor; /*! @var imminentState Usually the same as myCurrentState, except right after calling powerStateWillChangeTo. */ unsigned long imminentState; /*! @function serialize Serialize private instance variables for debug output (IORegistryDumper). */ virtual bool serialize(OSSerialize *s) const; }; /*! @class IOPMprott @abstract Protected power management instance variables for IOService objects. */ class IOPMprot : public OSObject //management { friend class IOService; OSDeclareDefaultStructors(IOPMprot) public: /*! @var ourName From getName(), used in logging. */ const char * ourName; /*! @var thePlatform From getPlatform, used in logging and registering. */ IOPlatformExpert * thePlatform; /*! @var theNumberOfPowerStates The number of states in the array. */ unsigned long theNumberOfPowerStates; // the number of states in the array /*! @var thePowerStates The array. */ IOPMPowerState thePowerStates[IOPMMaxPowerStates]; /*! @var theControllingDriver Points to the controlling driver. */ IOService * theControllingDriver; /*! @var aggressiveness Current value of power management aggressiveness. */ unsigned long aggressiveness; /*! @var current_aggressiveness_values Array of aggressiveness values. */ unsigned long current_aggressiveness_values [kMaxType+1]; /*! @var current_aggressiveness_validity True for values that are currently valid. */ bool current_aggressiveness_valid [kMaxType+1]; /*! @var myCurrentState The ordinal of our current power state. */ unsigned long myCurrentState; /*! @var parentsKnowState True if all our parents know the state of their power domain. */ bool parentsKnowState; /*! @var parentsCurrentPowerFlags Logical OR of power flags for the current state of each power domainparent. */ IOPMPowerFlags parentsCurrentPowerFlags; /*! @var maxCapability Ordinal of highest state we can achieve in current power domain state. */ unsigned long maxCapability; /*! @var PMworkloop Points to the single power management workloop. */ IOWorkLoop * PMworkloop; /*! @var commandQueue Used to serialize idle-power-down and busy-power-up. */ IOCommandQueue * commandQueue; /*! @var PMcommandGate Used to serialize timer expirations and incoming acknowledgements. */ IOCommandGate * PMcommandGate; /*! @var myCharacterFlags Logical OR of all output power character flags in the array. */ IOPMPowerFlags myCharacterFlags; /*! @var serialNumber Used to uniquely identify power management notification to apps and clients. */ UInt16 serialNumber; /*! @var responseFlags Points to an OSArray which manages responses from notified apps and clients. */ OSArray* responseFlags; /*! @var doNotPowerDown Keeps track of any negative responses from notified apps and clients. */ bool doNotPowerDown; /*! @var childLock Used to serialize scanning the children. */ IOLock * childLock; /*! @var parentLock Used to serialize scanning the parents. */ IOLock * parentLock; /*! @var outofbandparameter Used to communicate desired function to tellClientsWithResponse(). This is used because it avoids changing the signatures of the affected virtual methods. */ int outofbandparameter; /*! @function serialize Serialize protected instance variables for debug output (IORegistryDumper). */ virtual bool serialize(OSSerialize *s) const; };