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/IOPMinformeeList.h> 30 #include <IOKit/pwr_mgt/IOPMinformee.h> 31 32 #define super OSObject 33 OSDefineMetaClassAndStructors(IOPMinformeeList,OSObject) 34 35 //********************************************************************************* 36 // init 37 // 38 //********************************************************************************* 39 void IOPMinformeeList::initialize ( void ) 40 { 41 firstItem = NULL; 42 length = 0; 43 } 44 45 //****************************************************************************** 46 // getSharedRecursiveLock 47 // 48 //****************************************************************************** 49 IORecursiveLock *IOPMinformeeList::getSharedRecursiveLock( void ) 50 { 51 static IORecursiveLock *sharedListLock = NULL; 52 53 /* A running system could have 50-60+ instances of IOPMInformeeList. 54 * They'll share this lock, since list insertion and removal is relatively 55 * rare, and generally tied to major events like device discovery. 56 * 57 * getSharedRecursiveLock() is called from IOStartIOKit to initialize 58 * the sharedListLock before any IOPMinformeeLists are instantiated. 59 * 60 * The IOPMinformeeList class will be around for the lifetime of the system, 61 * we don't worry about freeing this lock. 62 */ 63 64 if ( NULL == sharedListLock ) 65 { 66 sharedListLock = IORecursiveLockAlloc(); 67 } 68 return sharedListLock; 69 } 70 71 //********************************************************************************* 72 // appendNewInformee 73 // 74 //********************************************************************************* 75 IOPMinformee *IOPMinformeeList::appendNewInformee ( IOService * newObject ) 76 { 77 IOPMinformee * newInformee; 78 79 if (!newObject) 80 return NULL; 81 82 newInformee = IOPMinformee::withObject (newObject); 83 84 if (!newInformee) 85 return NULL; 86 87 if( IOPMNoErr == addToList (newInformee)) 88 return newInformee; 89 else 90 return NULL; 91 } 92 93 94 //********************************************************************************* 95 // addToList 96 // *OBSOLETE* do not call from outside of this file. 97 // Try appendNewInformee() instead 98 //********************************************************************************* 99 IOReturn IOPMinformeeList::addToList ( IOPMinformee * newInformee ) 100 { 101 IOPMinformee * nextInformee; 102 IORecursiveLock *listLock = getSharedRecursiveLock(); 103 104 if(!listLock) 105 return kIOReturnError; 106 107 IORecursiveLockLock(listLock); 108 nextInformee = firstItem; 109 110 // Is new object already in the list? 111 while ( nextInformee != NULL ) 112 { 113 if ( nextInformee->whatObject == newInformee->whatObject ) 114 { 115 // object is present; just exit 116 goto unlock_and_exit; 117 } 118 nextInformee = nextInList(nextInformee); 119 } 120 121 // add it to the front of the list 122 newInformee->nextInList = firstItem; 123 firstItem = newInformee; 124 length++; 125 126 unlock_and_exit: 127 IORecursiveLockUnlock(listLock); 128 return IOPMNoErr; 129 } 130 131 132 //********************************************************************************* 133 // removeFromList 134 // 135 // Find the item in the list, unlink it, and free it. 136 //********************************************************************************* 137 138 IOReturn IOPMinformeeList::removeFromList ( IOService * theItem ) 139 { 140 IOPMinformee * item = firstItem; 141 IOPMinformee * temp; 142 IORecursiveLock *listLock = getSharedRecursiveLock(); 143 144 if ( NULL == item ) 145 return IOPMNoErr; 146 if(!listLock) 147 return kIOReturnError; 148 149 IORecursiveLockLock( listLock ); 150 151 if ( item->whatObject == theItem ) 152 { 153 firstItem = item->nextInList; 154 length--; 155 item->release(); 156 goto unlock_and_exit; 157 } 158 159 while ( item->nextInList != NULL ) 160 { 161 if ( item->nextInList->whatObject == theItem ) 162 { 163 temp = item->nextInList; 164 item->nextInList = temp->nextInList; 165 length--; 166 temp->release(); 167 goto unlock_and_exit; 168 } 169 item = item->nextInList; 170 } 171 172 unlock_and_exit: 173 IORecursiveLockUnlock(listLock); 174 return IOPMNoErr; 175 } 176 177 178 //********************************************************************************* 179 // firstInList 180 // 181 //********************************************************************************* 182 183 IOPMinformee * IOPMinformeeList::firstInList ( void ) 184 { 185 return firstItem; 186 } 187 188 //********************************************************************************* 189 // nextInList 190 // 191 //********************************************************************************* 192 193 IOPMinformee * IOPMinformeeList::nextInList ( IOPMinformee * currentItem ) 194 { 195 if ( currentItem != NULL ) { 196 return (currentItem->nextInList); 197 } 198 return NULL; 199 } 200 201 //********************************************************************************* 202 // numberOfItems 203 // 204 //********************************************************************************* 205 206 unsigned long IOPMinformeeList::numberOfItems ( void ) 207 { 208 return length; 209 } 210 211 //********************************************************************************* 212 // findItem 213 // 214 // Look through the list for the one which points to the object identified 215 // by the parameter. Return a pointer to the list item or NULL. 216 //********************************************************************************* 217 218 IOPMinformee * IOPMinformeeList::findItem ( IOService * driverOrChild ) 219 { 220 IOPMinformee * nextObject; 221 222 nextObject = firstInList(); 223 while ( nextObject != NULL ) { 224 if ( nextObject->whatObject == driverOrChild ) { 225 return nextObject; 226 } 227 nextObject = nextInList(nextObject); 228 } 229 return NULL; 230 } 231 232 233 234 //********************************************************************************* 235 // free 236 // 237 // Free all items in the list, and then free the list itself 238 //********************************************************************************* 239 240 void IOPMinformeeList::free (void ) 241 { 242 IOPMinformee * next = firstItem; 243 244 while ( next != NULL ) { 245 firstItem = next->nextInList; 246 length--; 247 next->release(); 248 next = firstItem; 249 } 250 super::free(); 251 } 252 253