|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: #include <IOKit/IOWorkLoop.h>
23: #include <IOKit/IOCommandQueue.h>
24: #include <IOKit/IOPlatformExpert.h>
25: #include <IOKit/pwr_mgt/RootDomain.h>
26: #include "RootDomainUserClient.h"
27:
28: extern "C" {
29: extern void kprintf(const char *, ...);
30: }
31:
32: void PMreceiveCmd ( OSObject *, void *, void *, void *, void * );
33:
34:
35: #define number_of_power_states 2
36: #define powerOff 0
37: #define powerOn 1
38:
39: static IOPMPowerState ourPowerStates[number_of_power_states] = {
40: {1,0,0,0,0,0,0,0,0,0,0,0},
41: {1,0,IOPMPowerOn,IOPMPowerOn,0,0,0,0,000000,0,0,0},
42: };
43:
44: #define super IOService
45: OSDefineMetaClassAndStructors(IOPMrootDomain,IOService)
46:
47:
48: // **********************************************************************************
49: // start
50: //
51: // We don't do much here. The real initialization occurs when the platform
52: // expert informs us we are the root.
53: // **********************************************************************************
54: bool IOPMrootDomain::start ( IOService * nub )
55: {
56: super::start(nub);
57: PMinit();
58: return true;
59: }
60:
61:
62: //*********************************************************************************
63: // youAreRoot
64: //
65: // Power Managment is informing us that we are the root power domain.
66: // The only difference between us and any other power domain is that
67: // we have no parent and therefore never call it.
68: //
69: // We complete our initialization here.
70: //*********************************************************************************
71: IOReturn IOPMrootDomain::youAreRoot ( void )
72: {
73: super::youAreRoot();
74: pm_vars->PMworkloop = IOWorkLoop::workLoop(); // make the workloop
75: if ( ! pm_vars->PMworkloop ) {
76: return IOPMNoErr;
77: }
78: pm_vars->commandQueue = IOCommandQueue::commandQueue(this, PMreceiveCmd); // make a command queue
79: if (! pm_vars->commandQueue ||
80: ( pm_vars->PMworkloop->addEventSource( pm_vars->commandQueue) != kIOReturnSuccess) ) {
81: return IOPMNoErr;
82: }
83:
84: pm_vars->aggressiveness = 640;
85: current_values[kPMGeneralAggressiveness] = pm_vars->aggressiveness;
86:
87: // Clamp power on. We will revisit this decision when the login window is displayed
88: // and we receive preferences via SetAggressiveness.
89: makeUsable();
90:
91: registerControllingDriver(this,ourPowerStates,number_of_power_states);
92:
93:
94: return IOPMNoErr;
95: }
96:
97:
98: // **********************************************************************************
99: // command_received
100: //
101: // We have received a command from ourselves on the command queue.
102: // If it is to send a recently-received aggressiveness factor, do so.
103: // Otherwise, it's something the superclass enqueued.
104: // **********************************************************************************
105: void IOPMrootDomain::command_received ( void * command, void * x, void * y, void * z )
106: {
107: switch ( (int)command ) {
108: case kPMbroadcastAggressiveness:
109: super::setAggressiveness((unsigned long)x,(unsigned long)y);
110: if ( (int)x == kPMMinutesToSleep ) {
111: if ( (int)y == 0 ) {
112: changeStateToPriv(powerOn); // no sleep, clamp power on
113: }
114: else {
115: changeStateToPriv(powerOff); // let it sleep when children are all asleep
116: }
117: }
118: break;
119: case kPMsleepDemand:
120: changeStateToPriv(powerOff); // force root domain off
121: overrideOnPriv();
122: break;
123: case kPMwakeSignal:
124: super::systemWake(); // broadcast wake to power tree
125: overrideOffPriv(); // allow children to wake us up
126: break;
127: default:
128: super::command_received(command,x,y,z);
129: break;
130: }
131: }
132:
133:
134: //*********************************************************************************
135: // setAggressiveness
136: //
137: // Some aggressiveness factor has changed. We put this change on our
138: // command queue so that we can broadcast it to the hierarchy while on
139: // the Power Mangement workloop thread. This enables objects in the
140: // hierarchy to successfully alter their idle timers, which are all on the
141: // same thread.
142: //*********************************************************************************
143:
144: IOReturn IOPMrootDomain::setAggressiveness ( unsigned long type, unsigned long newLevel )
145: {
146: if ( type <= kMaxType ) {
147: current_values[type] = newLevel;
148: }
149: pm_vars->commandQueue->enqueueCommand(true, (void *)kPMbroadcastAggressiveness, (void *) type, (void *) newLevel );
150: return kIOReturnSuccess;
151: }
152:
153:
154: //*********************************************************************************
155: // getAggressiveness
156: //
157: // Called by the user client.
158: //*********************************************************************************
159:
160: IOReturn IOPMrootDomain::getAggressiveness ( unsigned long type, unsigned long * currentLevel )
161: {
162: if ( type <= kMaxType ) {
163: *currentLevel = current_values[type];
164: }
165: return kIOReturnSuccess;
166: }
167:
168:
169: // **********************************************************************************
170: // sleepSystem
171: //
172: // **********************************************************************************
173: IOReturn IOPMrootDomain::sleepSystem ( void )
174: {
175: kprintf("sleep demand received\n");
176: pm_vars->commandQueue->enqueueCommand(true, (void *)kPMsleepDemand );
177:
178: return kIOReturnSuccess;
179: }
180:
181:
182:
183: // **********************************************************************************
184: // wakeSystem
185: //
186: // **********************************************************************************
187: IOReturn IOPMrootDomain::wakeSystem ( void )
188: {
189: pm_vars->commandQueue->enqueueCommand(true, (void *)kPMwakeSignal );
190:
191: return kIOReturnSuccess;
192: }
193:
194:
195:
196: //*********************************************************************************
197: // initialPowerStateForDomainState
198: //
199: // Assume that power is initially on in the root power domain.
200: //*********************************************************************************
201:
202: unsigned long IOPMrootDomain::initialPowerStateForDomainState ( IOPMPowerFlags )
203: {
204: return powerOn;
205: }
206:
207:
208: // **********************************************************************************
209: // setPowerState
210: //
211: // **********************************************************************************
212: IOReturn IOPMrootDomain::setPowerState ( unsigned long powerStateOrdinal, IOService* whatDevice)
213: {
214: if ( powerStateOrdinal == powerOff ) {
215: kprintf("system would sleep here\n");
216: }
217: return IOPMAckImplied;
218: }
219:
220:
221: // **********************************************************************************
222: // newUserClient
223: //
224: // **********************************************************************************
225: IOReturn IOPMrootDomain::newUserClient( task_t owningTask, void * /* security_id */, UInt32 type, IOUserClient ** handler )
226: {
227: IOReturn err = kIOReturnSuccess;
228: RootDomainUserClient * client;
229:
230: client = RootDomainUserClient::withTask(owningTask);
231:
232: if( !client || (false == client->attach( this )) ||
233: (false == client->start( this )) ) {
234: if(client) {
235: client->detach( this );
236: client->release();
237: client = NULL;
238: }
239: err = kIOReturnNoMemory;
240: }
241: *handler = client;
242: return err;
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.