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 33OSDefineMetaClassAndStructors(IOPMinformeeList,OSObject) 34 35//********************************************************************************* 36// init 37// 38//********************************************************************************* 39void IOPMinformeeList::initialize ( void ) 40{ 41 firstItem = NULL; 42 length = 0; 43} 44 45//****************************************************************************** 46// getSharedRecursiveLock 47// 48//****************************************************************************** 49IORecursiveLock *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 //********************************************************************************* 75IOPMinformee *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//********************************************************************************* 99IOReturn 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 126unlock_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 138IOReturn 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 172unlock_and_exit: 173 IORecursiveLockUnlock(listLock); 174 return IOPMNoErr; 175} 176 177 178//********************************************************************************* 179// firstInList 180// 181//********************************************************************************* 182 183IOPMinformee * IOPMinformeeList::firstInList ( void ) 184{ 185 return firstItem; 186} 187 188//********************************************************************************* 189// nextInList 190// 191//********************************************************************************* 192 193IOPMinformee * 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 206unsigned 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 218IOPMinformee * 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 240void 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 } 250super::free(); 251} 252 253