void IORecursiveLockLock( IORecursiveLock * _lock) { _IORecursiveLock * lock = (_IORecursiveLock *)_lock; if( lock->thread == IOThreadSelf()) lock->count++; else { mutex_lock( lock->mutex ); assert( lock->thread == 0 ); assert( lock->count == 0 ); lock->thread = IOThreadSelf(); lock->count = 1; } }
boolean_t IORecursiveLockTryLock( IORecursiveLock * _lock) { _IORecursiveLock * lock = (_IORecursiveLock *)_lock; if( lock->thread == IOThreadSelf()) { lock->count++; return( true ); } else { if( mutex_try( lock->mutex )) { assert( lock->thread == 0 ); assert( lock->count == 0 ); lock->thread = IOThreadSelf(); lock->count = 1; return( true ); } } return( false ); }
unsigned long UniNEnet::powerStateForDomainState(IOPMPowerFlags domainState ) { ELG( IOThreadSelf(), domainState, 'ps4d', "UniNEnet::powerStateForDomainState" ); if ( domainState & IOPMPowerOn ) return 1; // This should answer What If? return 0; }/* end powerStateForDomainState */
unsigned long UniNEnet::maxCapabilityForDomainState( IOPMPowerFlags domainState ) { ELG( IOThreadSelf(), domainState, 'mx4d', "maxCapabilityForDomainState" ); if ( domainState & IOPMPowerOn ) return kNumOfPowerStates - 1; return 0; }/* end maxCapabilityForDomainState */
unsigned long UniNEnet::initialPowerStateForDomainState( IOPMPowerFlags domainState ) { ELG( IOThreadSelf(), domainState, 'ip4d', "initialPowerStateForDomainState" ); if ( domainState & IOPMPowerOn ) return kNumOfPowerStates - 1; return 0; }/* end initialPowerStateForDomainState */
void IORecursiveLockUnlock( IORecursiveLock * _lock) { _IORecursiveLock * lock = (_IORecursiveLock *)_lock; assert( lock->thread == IOThreadSelf() ); if( 0 == (--lock->count)) { lock->thread = 0; mutex_unlock( lock->mutex ); } }
int IORecursiveLockSleep(IORecursiveLock *_lock, void *event, UInt32 interType) { _IORecursiveLock * lock = (_IORecursiveLock *)_lock; UInt32 count = lock->count; int res; assert(lock->thread == IOThreadSelf()); assert(lock->count == 1 || interType == THREAD_UNINT); lock->count = 0; lock->thread = 0; res = thread_sleep_mutex((event_t) event, lock->mutex, (int) interType); // Must re-establish the recursive lock no matter why we woke up // otherwise we would potentially leave the return path corrupted. assert(lock->thread == 0); assert(lock->count == 0); lock->thread = IOThreadSelf(); lock->count = count; return res; }
IOReturn UniNEnet::registerWithPolicyMaker( IOService *policyMaker ) { IOReturn rc; if ( fBuiltin ) rc = policyMaker->registerPowerDriver( this, ourPowerStates, kNumOfPowerStates ); else rc = super::registerWithPolicyMaker( policyMaker ); // return unsupported ELG( IOThreadSelf(), rc, 'RwPM', "registerWithPolicyMaker" ); return rc; }/* end registerWithPolicyMaker */
bool IOFWWorkLoop::tryCloseGate() { bool ret; ret = IOWorkLoop::tryCloseGate(); if( ret && fSleepToken && (fRemoveSourceThread != IOThreadSelf()) ) { openGate(); ret = false; } return ret; }
IOReturn IOFWWorkLoop::removeEventSource(IOEventSource *toRemove) { IOReturn status = kIOReturnSuccess; // the PM thread retains ioservices while fiddling with them // that means the PM thread may be the thread that releases the final retain on an ioservices // ioservices may remove and free event sources in their free routines // removing and freeing event sources grabs the workloop lock // if the PM has already put FireWire to sleep we would sleep any thread who grabs the workloop lock // if we sleep the PM thread then sleep hangs. that's bad. // if we could have a do over we should not sleep the entire workloop, but only those that belong // to the core FireWire services. at this point though there are likely too many drivers relying // on a full workloop sleep to change things safely. // so for now we do these slightly crazy machinations to allow event source removal without sleeping the // calling thread // we only need to do this if the calling thread is the PM workloop, but I don't want to make // assumptions about PM internals that may change so I'll do this for all threads IOWorkLoop::closeGate(); if( fRemoveSourceThread != NULL ) { IOLog( "IOFWWorkLoop::removeEventSource - fRemoveSourceThread = (%p) != NULL\n", fRemoveSourceThread ); } // remember who's removing the event source fRemoveSourceThread = IOThreadSelf(); // if we're asleep if( fSleepToken ) { // we can't let this object be freed after we return since freeing a command gate grabs the workloop lock // we will flush this set on wake fRemoveSourceDeferredSet->setObject( toRemove ); } // do the actual removal, this will succeed since fRemoveSourceThread will be allowed to grab the lock status = IOWorkLoop::removeEventSource( toRemove ); // forget the thread fRemoveSourceThread = NULL; IOWorkLoop::openGate(); return status; }
void IOFWWorkLoop::closeGate() { IOWorkLoop::closeGate(); if( fSleepToken && (fRemoveSourceThread != IOThreadSelf()) ) { IOReturn res; do { res = sleepGate( fSleepToken, THREAD_ABORTSAFE ); if( res == kIOReturnSuccess ) break; IOLog("sleepGate returned 0x%x\n", res); } while( true ); } }
bool IOWorkLoop::onThread() const { return (IOThreadSelf() == workThread); }
bool RTL8139::start( IOService *provider ) { OSObject *builtinProperty; bool success = false; ELG( IOThreadSelf(), provider, 'Strt', "RTL8139::start - this, provider." ); DEBUG_LOG( "start() ===>\n" ); do { if ( false == super::start( provider ) ) // Start our superclass first break; // Save a reference to our provider. pciNub = OSDynamicCast( IOPCIDevice, provider ); if ( 0 == pciNub ) break; pciNub->retain(); // Retain provider, released in free(). if ( false == pciNub->open( this ) ) // Open our provider. break; fBuiltin = false; builtinProperty = provider->getProperty( "built-in" ); if ( builtinProperty ) { fBuiltin = true; ELG( 0, 0, 'b-in', "RTL8139::start - found built-in property." ); } if ( false == initEventSources( provider ) ) break; // Allocate memory for descriptors. This function will leak memory // if called more than once. So don't do it. if ( false == allocateDescriptorMemory() ) break; // Get the virtual address mapping of CSR registers located at // Base Address Range 0 (0x10). csrMap = pciNub->mapDeviceMemoryWithRegister( kIOPCIConfigBaseAddress1 ); if ( 0 == csrMap ) break; csrBase = (volatile void*)csrMap->getVirtualAddress(); // Init PCI config space: if ( false == initPCIConfigSpace( pciNub ) ) break; // Reset chip to bring it to a known state. if ( initAdapter( kResetChip ) == false ) { IOLog( "%s: initAdapter() failed\n", getName() ); break; } registerEEPROM(); // Publish our media capabilities: phyProbeMediaCapability(); if ( false == publishMediumDictionary( mediumDict ) ) break; success = true; } while ( false ); // Close our provider, it will be re-opened on demand when // our enable() is called by a client. if ( pciNub ) pciNub->close( this ); do { if ( false == success ) break; success = false; // Allocate and attach an IOEthernetInterface instance. if ( false == attachInterface( (IONetworkInterface**)&netif, false) ) break; // Optional: this driver supports kernel debugging. attachDebuggerClient( &debugger ); // Trigger matching for clients of netif. netif->registerService(); success = true; } while ( false ); DEBUG_LOG( "start() <===\n" ); return success; }/* end start */
boolean_t IORecursiveLockHaveLock( const IORecursiveLock * _lock) { _IORecursiveLock * lock = (_IORecursiveLock *)_lock; return( lock->thread == IOThreadSelf()); }