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