]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOPMchangeNoteList.cpp
faf7b06010d93d1ba795403a1bab14cf06bca56d
[apple/xnu.git] / iokit / Kernel / IOPMchangeNoteList.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 #include <IOKit/pwr_mgt/IOPM.h>
31 #include <IOKit/pwr_mgt/IOPMchangeNoteList.h>
32 #include <IOKit/pwr_mgt/IOPowerConnection.h>
33
34 #define super OSObject
35 OSDefineMetaClassAndStructors(IOPMchangeNoteList,OSObject)
36
37 //*********************************************************************************
38 // init
39 //
40 //*********************************************************************************
41 void IOPMchangeNoteList::initialize ( void )
42 {
43 long i;
44
45 firstInList = 0;
46 firstUnused = 0;
47 for ( i = 0; i < IOPMMaxChangeNotes; i++ ) {
48 changeNote[i].flags = IOPMNotInUse;
49 }
50 }
51
52 //*********************************************************************************
53 // createChangeNote
54 //
55 //*********************************************************************************
56
57 long IOPMchangeNoteList::createChangeNote ( void )
58 {
59 unsigned long i, j;
60
61 i = increment(firstUnused);
62 if ( firstInList == i ) {
63 return -1;
64 }
65 j = firstUnused;
66 firstUnused = i;
67
68 return j;
69 }
70
71 //*********************************************************************************
72 // currentChange
73 //
74 // Return the ordinal of the first change note in the list.
75 // If the list is empty, return -1.
76 //*********************************************************************************
77
78 long IOPMchangeNoteList::currentChange ( void )
79 {
80 if ( firstUnused == firstInList ) {
81 return -1;
82 }
83 else {
84 return firstInList;
85 }
86 }
87
88 //*********************************************************************************
89 // latestChange
90 //
91 // Return the ordinal of the last change note in the list.
92 // If the list is empty, return -1.
93 //*********************************************************************************
94
95 long IOPMchangeNoteList::latestChange ( void )
96 {
97 if ( firstUnused == firstInList ) {
98 return -1;
99 }
100 else {
101 return decrement(firstUnused);
102 }
103 }
104
105 //*********************************************************************************
106 // releaseHeadChangeNote
107 //
108 // Mark the head node unused.
109 // This happens when the first change in the list is completely processed.
110 // That is, all interested parties have acknowledged it, and power is settled
111 // at the new level.
112 //*********************************************************************************
113
114 IOReturn IOPMchangeNoteList::releaseHeadChangeNote ( void )
115 {
116 IOPowerConnection *tmp;
117
118 if((tmp = changeNote[firstInList].parent)) {
119 changeNote[firstInList].parent = 0;
120 tmp->release();
121 }
122
123 changeNote[firstInList].flags = IOPMNotInUse;
124 firstInList = increment(firstInList);
125 return IOPMNoErr;
126 }
127
128 //*********************************************************************************
129 // releaseTailChangeNote
130 //
131 // Mark the tail node unused.
132 // This happens when a power change is queued up after another which has
133 // not yet been started, and the second one supercedes the first. The data in
134 // the second is copied into the first and the the second is released. This
135 // collapses the first change out of the list.
136 //*********************************************************************************
137
138 IOReturn IOPMchangeNoteList::releaseTailChangeNote ( void )
139 {
140 IOPowerConnection *tmp;
141
142 if((tmp = changeNote[firstInList].parent)) {
143 changeNote[firstInList].parent = 0;
144 tmp->release();
145 }
146
147 firstUnused = decrement(firstUnused);
148 changeNote[firstUnused].flags = IOPMNotInUse;
149 return IOPMNoErr;
150 }
151
152 //*********************************************************************************
153 // changeNoteInUse
154 //
155 //*********************************************************************************
156
157 bool IOPMchangeNoteList::changeNoteInUse ( unsigned long ordinal )
158 {
159 if ( changeNote[ordinal].flags == IOPMNotInUse ) {
160 return false;
161 }
162 else {
163 return true;
164 }
165 }
166
167 //*********************************************************************************
168 // nextChangeNote
169 //
170 // If the parameter corresponds to the most recent power change notification
171 // passed to drivers and children, return -1. Otherwise, return the array
172 // position of the next notification in the circular list.
173 //*********************************************************************************
174
175 long IOPMchangeNoteList::nextChangeNote ( unsigned long ordinal )
176 {
177 unsigned long i;
178
179 i = increment(ordinal);
180 if ( i == firstUnused) {
181 return -1;
182 }
183 return ( i );
184 }
185
186 //*********************************************************************************
187 // increment
188 //
189 // Increment the parameter mod the circular list size and return it.
190 //*********************************************************************************
191
192 unsigned long IOPMchangeNoteList::increment ( unsigned long ordinal )
193 {
194 if ( ordinal == (IOPMMaxChangeNotes - 1) ) {
195 return 0;
196 }
197 else {
198 return ordinal + 1;
199 }
200 }
201
202 //*********************************************************************************
203 // decrement
204 //
205 // Decrement the parameter mod the circular list size and return it.
206 //*********************************************************************************
207
208 unsigned long IOPMchangeNoteList::decrement ( unsigned long ordinal )
209 {
210 if ( ordinal == 0 ) {
211 return IOPMMaxChangeNotes - 1;
212 }
213 else {
214 return ordinal - 1;
215 }
216 }
217
218 //*********************************************************************************
219 // previousChangeNote
220 //
221 // If the parameter corresponds to the oldest power change notification
222 // passed to drivers and children, return -1. Otherwise, return the array
223 // position of the previous notification in the circular list.
224 //*********************************************************************************
225
226 long IOPMchangeNoteList::previousChangeNote ( unsigned long ordinal )
227 {
228 if ( ordinal == firstInList ) {
229 return -1;
230 }
231 return decrement(ordinal);
232 }
233
234 //*********************************************************************************
235 // listEmpty
236 //
237 //*********************************************************************************
238
239 bool IOPMchangeNoteList::listEmpty ( void )
240 {
241 return ( firstInList == firstUnused ) ;
242 }