]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOPMchangeNoteList.cpp
xnu-792.21.3.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPMchangeNoteList.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, 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 #include <IOKit/pwr_mgt/IOPM.h>
29 #include <IOKit/pwr_mgt/IOPMchangeNoteList.h>
30 #include <IOKit/pwr_mgt/IOPowerConnection.h>
31
32 #define super OSObject
33 OSDefineMetaClassAndStructors(IOPMchangeNoteList,OSObject)
34
35 //*********************************************************************************
36 // init
37 //
38 //*********************************************************************************
39 void IOPMchangeNoteList::initialize ( void )
40 {
41 long i;
42
43 firstInList = 0;
44 firstUnused = 0;
45 for ( i = 0; i < IOPMMaxChangeNotes; i++ ) {
46 changeNote[i].flags = IOPMNotInUse;
47 }
48 }
49
50 //*********************************************************************************
51 // createChangeNote
52 //
53 //*********************************************************************************
54
55 long IOPMchangeNoteList::createChangeNote ( void )
56 {
57 unsigned long i, j;
58
59 i = increment(firstUnused);
60 if ( firstInList == i ) {
61 return -1;
62 }
63 j = firstUnused;
64 firstUnused = i;
65
66 return j;
67 }
68
69 //*********************************************************************************
70 // currentChange
71 //
72 // Return the ordinal of the first change note in the list.
73 // If the list is empty, return -1.
74 //*********************************************************************************
75
76 long IOPMchangeNoteList::currentChange ( void )
77 {
78 if ( firstUnused == firstInList ) {
79 return -1;
80 }
81 else {
82 return firstInList;
83 }
84 }
85
86 //*********************************************************************************
87 // latestChange
88 //
89 // Return the ordinal of the last change note in the list.
90 // If the list is empty, return -1.
91 //*********************************************************************************
92
93 long IOPMchangeNoteList::latestChange ( void )
94 {
95 if ( firstUnused == firstInList ) {
96 return -1;
97 }
98 else {
99 return decrement(firstUnused);
100 }
101 }
102
103 //*********************************************************************************
104 // releaseHeadChangeNote
105 //
106 // Mark the head node unused.
107 // This happens when the first change in the list is completely processed.
108 // That is, all interested parties have acknowledged it, and power is settled
109 // at the new level.
110 //*********************************************************************************
111
112 IOReturn IOPMchangeNoteList::releaseHeadChangeNote ( void )
113 {
114 IOPowerConnection *tmp;
115
116 if((tmp = changeNote[firstInList].parent)) {
117 changeNote[firstInList].parent = 0;
118 tmp->release();
119 }
120
121 changeNote[firstInList].flags = IOPMNotInUse;
122 firstInList = increment(firstInList);
123 return IOPMNoErr;
124 }
125
126 //*********************************************************************************
127 // releaseTailChangeNote
128 //
129 // Mark the tail node unused.
130 // This happens when a power change is queued up after another which has
131 // not yet been started, and the second one supercedes the first. The data in
132 // the second is copied into the first and the the second is released. This
133 // collapses the first change out of the list.
134 //*********************************************************************************
135
136 IOReturn IOPMchangeNoteList::releaseTailChangeNote ( void )
137 {
138 IOPowerConnection *tmp;
139
140 if((tmp = changeNote[firstInList].parent)) {
141 changeNote[firstInList].parent = 0;
142 tmp->release();
143 }
144
145 firstUnused = decrement(firstUnused);
146 changeNote[firstUnused].flags = IOPMNotInUse;
147 return IOPMNoErr;
148 }
149
150 //*********************************************************************************
151 // changeNoteInUse
152 //
153 //*********************************************************************************
154
155 bool IOPMchangeNoteList::changeNoteInUse ( unsigned long ordinal )
156 {
157 if ( changeNote[ordinal].flags == IOPMNotInUse ) {
158 return false;
159 }
160 else {
161 return true;
162 }
163 }
164
165 //*********************************************************************************
166 // nextChangeNote
167 //
168 // If the parameter corresponds to the most recent power change notification
169 // passed to drivers and children, return -1. Otherwise, return the array
170 // position of the next notification in the circular list.
171 //*********************************************************************************
172
173 long IOPMchangeNoteList::nextChangeNote ( unsigned long ordinal )
174 {
175 unsigned long i;
176
177 i = increment(ordinal);
178 if ( i == firstUnused) {
179 return -1;
180 }
181 return ( i );
182 }
183
184 //*********************************************************************************
185 // increment
186 //
187 // Increment the parameter mod the circular list size and return it.
188 //*********************************************************************************
189
190 unsigned long IOPMchangeNoteList::increment ( unsigned long ordinal )
191 {
192 if ( ordinal == (IOPMMaxChangeNotes - 1) ) {
193 return 0;
194 }
195 else {
196 return ordinal + 1;
197 }
198 }
199
200 //*********************************************************************************
201 // decrement
202 //
203 // Decrement the parameter mod the circular list size and return it.
204 //*********************************************************************************
205
206 unsigned long IOPMchangeNoteList::decrement ( unsigned long ordinal )
207 {
208 if ( ordinal == 0 ) {
209 return IOPMMaxChangeNotes - 1;
210 }
211 else {
212 return ordinal - 1;
213 }
214 }
215
216 //*********************************************************************************
217 // previousChangeNote
218 //
219 // If the parameter corresponds to the oldest power change notification
220 // passed to drivers and children, return -1. Otherwise, return the array
221 // position of the previous notification in the circular list.
222 //*********************************************************************************
223
224 long IOPMchangeNoteList::previousChangeNote ( unsigned long ordinal )
225 {
226 if ( ordinal == firstInList ) {
227 return -1;
228 }
229 return decrement(ordinal);
230 }
231
232 //*********************************************************************************
233 // listEmpty
234 //
235 //*********************************************************************************
236
237 bool IOPMchangeNoteList::listEmpty ( void )
238 {
239 return ( firstInList == firstUnused ) ;
240 }