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