bool AiroJackUserClient::
start(IOService* provider)
{
    WLLogInfo("AiroJackUserClient::start()\n");

    if (!super::start(provider)) {
        WLLogErr("AiroJackUserClient: start: super::start() failed\n");
        return false;
    }

    _provider = OSDynamicCast(AiroJackDriver, provider);

    if (!_provider)
        return false;

    _wlCard = _provider->getWLCard();

    _userCommandGate = IOCommandGate::commandGate(this);
    if (!_userCommandGate) {
        WLLogErr("AiroJackUserClient::start: Couldn't get CommandGate\n");
        return false;
    }

    IOWorkLoop* wl = _provider->getWorkLoop();
    if (wl->addEventSource(_userCommandGate) != kIOReturnSuccess) {
        WLLogErr("AiroJackUserClient::start: Couldn't add gate to workloop\n");
        return false;
    }

    _packetQueue = _provider->getPacketQueue();

    return true;
}
bool
org_virtualbox_VBoxGuest::setupVmmDevInterrupts(IOService *pProvider)
{
    IOWorkLoop *pWorkLoop = getWorkLoop();

    if (!pWorkLoop)
        return false;

    m_pInterruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(this,
                                                                               &deferredInterruptHandler,
                                                                               &directInterruptHandler,
                                                                               pProvider);

    if (kIOReturnSuccess != pWorkLoop->addEventSource(m_pInterruptSrc))
    {
        m_pInterruptSrc->disable();
        m_pInterruptSrc->release();
        m_pInterruptSrc = 0;
        return false;
    }

    m_pInterruptSrc->enable();

    return true;
}
示例#3
0
/* virtual */ void IOCommandGate::setWorkLoop(IOWorkLoop *inWorkLoop)
{
    IOWorkLoop * wl;
    uintptr_t  * sleepersP = (uintptr_t *) &reserved;
    bool         defer;

    if (!inWorkLoop && (wl = workLoop)) {		// tearing down
	wl->closeGate();
	*sleepersP |= kSleepersRemoved;
	while (*sleepersP & kSleepersWaitEnabled) {
	    thread_wakeup_with_result(&enabled, THREAD_INTERRUPTED);
	    sleepGate(sleepersP, THREAD_UNINT);
	}
	*sleepersP &= ~kSleepersWaitEnabled;
	defer = (0 != (kSleepersActionsMask & *sleepersP));
	if (!defer)
	{
	    super::setWorkLoop(0);
	    *sleepersP &= ~kSleepersRemoved;
	}
	wl->openGate();
	return;
    }

    super::setWorkLoop(inWorkLoop);
}
void IOHIDEventSystemUserClient::stop( IOService * provider )
{
    IOWorkLoop * workLoop = getWorkLoop();
    if (workLoop && commandGate)
    {
        workLoop->removeEventSource(commandGate);
    }
}
示例#5
0
void SoftU2FUserClient::stop(IOService *provider) {
  IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider);

  IOWorkLoop *workLoop = getWorkLoop();
  if (workLoop && _commandGate)
    workLoop->removeEventSource(_commandGate);

  super::stop(provider);
}
示例#6
0
bool	AREngine::initHardware(IOService* inProvider)
{
	bool theAnswer = false;
	
	if(IOAudioEngine::initHardware(inProvider))
	{
		IOAudioSampleRate theInitialSampleRate = { 0, 0 };
		UInt32 theNumberChannels = 0;
		
		//	create the streams
		if(CreateStreams(&theInitialSampleRate, &theNumberChannels) && (theInitialSampleRate.whole != 0))
		{
			CreateControls(theNumberChannels);
			
			//	figure out how long each block is in microseconds
			mBlockTimeoutMicroseconds = 1000000 * mBlockSize / theInitialSampleRate.whole;
			
			setSampleRate(&theInitialSampleRate);
			
			// Set the number of sample frames in each buffer
			setNumSampleFramesPerBuffer(mBlockSize * mNumberBlocks);
			
			//	set up the timer
			IOWorkLoop* theWorkLoop = getWorkLoop();
			if(theWorkLoop != NULL)
			{
				mTimerEventSource = IOTimerEventSource::timerEventSource(this, TimerFired);
				if(mTimerEventSource != NULL)
				{
					theWorkLoop->addEventSource(mTimerEventSource);
					theAnswer = true;
				}
			}
			
			//	set the safety offset
			//	note that due to cache issues, it probably isn't wise to leave the safety offset at 0,
			//	we set it to 4 here, just to be safe.
			setSampleOffset(4);
			
			//	set up the time stamp generator
			mTimeStampGenerator.SetSampleRate(theInitialSampleRate.whole);
			mTimeStampGenerator.SetFramesPerRingBuffer(mBlockSize * mNumberBlocks);
			
			//	nate that the rate scalar is a 4.28 fixed point number
			//	this means that each incremnt is 1/2^28
			mTimeStampGenerator.SetRateScalar(1UL << 28);
			
			//	set the maximum jitter
//			AbsoluteTime theMaximumJitter = { 0, 0 };
//			nanoseconds_to_absolutetime(5ULL * 1000ULL, &theMaximumJitter);
//			mTimeStampGenerator.SetMaximumJitter(theMaximumJitter.lo);
		}
	}
	
	return theAnswer;
}
示例#7
0
// start is called after initWithTask as a result of the user process calling
// IOServiceOpen.
bool SoftU2FUserClient::start(IOService *provider) {
  IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider);

  SoftU2FDevice *device = nullptr;
  IOWorkLoop *workLoop = nullptr;

  if (!OSDynamicCast(SoftU2FDriver, provider))
    goto fail_bad_provider;

  if (!super::start(provider))
    goto fail_super_start;

  device = SoftU2FDevice::newDevice();
  if (!device)
    goto fail_new_device;

  if (!device->attach(this))
    goto fail_device_attach;

  if (!device->start(this))
    goto fail_device_start;

  workLoop = getWorkLoop();
  if (!workLoop)
    goto fail_no_workloop;

  _commandGate = IOCommandGate::commandGate(this);
  if (!_commandGate)
    goto fail_new_cgate;

  if (workLoop->addEventSource(_commandGate) != kIOReturnSuccess)
    goto fail_add_event_source;

  // Our call to device->attach took a retain on the device when it was added to the registry.
  // That will be released when the device is detached from the registry.
  device->release();

  return true;

fail_add_event_source:
fail_new_cgate:
fail_no_workloop:
fail_device_start:
  device->detach(this);

fail_device_attach:
  device->release();

fail_new_device:
  stop(provider);

fail_super_start:
fail_bad_provider:
  return false;
}
bool RTL8139::initEventSources( IOService *provider )
{
	ELG( 0, 0, 'InES', "RTL8139::initEventSources - " );
    DEBUG_LOG( "initEventSources() ===>\n" );

	IOWorkLoop	*wl = getWorkLoop();
	if ( 0 == wl )
        return false;

	fTransmitQueue = getOutputQueue();
	if ( 0 == fTransmitQueue )
        return false;
	fTransmitQueue->setCapacity( kTransmitQueueCapacity );

		// Create an interrupt event source to handle hardware interrupts.

	interruptSrc = IOInterruptEventSource::interruptEventSource(
						this,
					   OSMemberFunctionCast(	IOInterruptEventAction,
												this,
												&RTL8139::interruptOccurred ),
					   provider );

	if ( !interruptSrc || (wl->addEventSource( interruptSrc ) != kIOReturnSuccess) )
		return false;

		// This is important. If the interrupt line is shared with other devices,
		// then the interrupt vector will be enabled only if all corresponding
		// interrupt event sources are enabled. To avoid masking interrupts for
		// other devices that are sharing the interrupt line, the event source
		// is enabled immediately. Hardware interrupt sources remain disabled.

    interruptSrc->enable();

		// Register a timer event source used as a watchdog timer:

	timerSrc = IOTimerEventSource::timerEventSource(
					this,
					OSMemberFunctionCast(	IOTimerEventSource::Action,
											this,
											&RTL8139::timeoutOccurred ) );

	if ( !timerSrc || (wl->addEventSource( timerSrc ) != kIOReturnSuccess) )
		return false;

		// Create a dictionary to hold IONetworkMedium objects:

	mediumDict = OSDictionary::withCapacity( 5 );
	if ( 0 == mediumDict )
		return false;

	DEBUG_LOG( "initEventSources() <===\n" );
	return true;
}/* end initEventSources */
void IOFireWireSBP2LUN::free( void )
{
	FWKLOG( ( "IOFireWireSBP2LUN<%p> : free\n", this ) );

	//
	// free unreleased orbs
	//
	
//	flushAllManagementORBs();
		
	if( fORBSetIterator )			
		fORBSetIterator->release();

	if( fORBSet )
		fORBSet->release();

    //
    // release login set
    //
    
	if( fLoginSetIterator )			
		fLoginSetIterator->release();

	if( fLoginSet )
		fLoginSet->release();

	//
	// destroy command gate
	//
	
	if( fGate != NULL )
	{
		IOWorkLoop * workLoop = NULL;

		workLoop = fGate->getWorkLoop();
		workLoop->removeEventSource( fGate );
		workLoop->release();

		fGate->release();
		fGate = NULL;
	}
	
	if( fProviderTarget )
	{
		fProviderTarget->release();
		fProviderTarget = NULL;
	}
			
	IOService::free();
}
示例#10
0
void BrcmPatchRAM::stop(IOService* provider)
{
    uint64_t stop_time, nano_secs;
    clock_get_uptime(&stop_time);
    absolutetime_to_nanoseconds(stop_time - wake_time, &nano_secs);
    uint64_t milli_secs = nano_secs / 1000000;
    AlwaysLog("Time since wake %llu.%llu seconds.\n", milli_secs / 1000, milli_secs % 1000);


    DebugLog("stop\n");

    OSSafeReleaseNULL(mFirmwareStore);

    IOWorkLoop* workLoop = getWorkLoop();
    if (workLoop)
    {
        if (mTimer)
        {
            mTimer->cancelTimeout();
            workLoop->removeEventSource(mTimer);
            mTimer->release();
            mTimer = NULL;
        }
        if (mWorkSource)
        {
            workLoop->removeEventSource(mWorkSource);
            mWorkSource->release();
            mWorkSource = NULL;
            mWorkPending = 0;
        }
    }

    PMstop();

    if (mCompletionLock)
    {
        IOLockFree(mCompletionLock);
        mCompletionLock = NULL;
    }
    if (mWorkLock)
    {
        IOLockFree(mWorkLock);
        mWorkLock = NULL;
    }

    OSSafeReleaseNULL(mDevice);

    super::stop(provider);
}
示例#11
0
void
IOCommandPool::free(void)
{
    if (fSerializer) {
        // remove our event source from owner's workloop
        IOWorkLoop *wl = fSerializer->getWorkLoop();
        if (wl)
            wl->removeEventSource(fSerializer);

        fSerializer->release();
        fSerializer = 0;
    }

    // Tell our superclass to cleanup too
    super::free();
}
//---------------------------------------------------------------------------
bool AgereET131x::initEventSources( IOService* provider )
{
	// Get a handle to our superclass' workloop.
	//
	IOWorkLoop* myWorkLoop = (IOWorkLoop *) getWorkLoop();
	if (myWorkLoop == NULL) {
		IOLog(" myWorkLoop is NULL.\n");
		return false;
	}
	
	transmitQueue = getOutputQueue();
	if (transmitQueue == NULL) {
		IOLog("getOutputQueue failed.\n");
		return false;
	}
	transmitQueue->setCapacity(NUM_TCB);
	
	interruptSource = IOFilterInterruptEventSource::filterInterruptEventSource( this, &AgereET131x::interruptHandler, &AgereET131x::interruptFilter, provider);
	
	if (!interruptSource ||
		(myWorkLoop->addEventSource(interruptSource) != kIOReturnSuccess)) {
		IOLog("workloop add eventsource interrupt source.\n");
		return false;
	}
	
	// This is important. If the interrupt line is shared with other devices,
	// then the interrupt vector will be enabled only if all corresponding
	// interrupt event sources are enabled. To avoid masking interrupts for
	// other devices that are sharing the interrupt line, the event source
	// is enabled immediately.
	interruptSource->enable();
	
	// Register a timer event source. This is used as a watchdog timer.
	//
	watchdogSource = IOTimerEventSource::timerEventSource(this, &AgereET131x::timeoutHandler );
	if (!watchdogSource || (myWorkLoop->addEventSource(watchdogSource) != kIOReturnSuccess)) {
		IOLog("watchdogSource create failed.\n");
		return false;
	}
	
	mediumDict = OSDictionary::withCapacity(MEDIUM_INDEX_COUNT + 1);
	if (mediumDict == NULL) {
		return false;
	}
	return true;
}
示例#13
0
bool org_virtualbox_VBoxGuest::disableVmmDevInterrupts(void)
{
    IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();

    if (!pWorkLoop)
        return false;

    if (!m_pInterruptSrc)
        return false;

    m_pInterruptSrc->disable();
    pWorkLoop->removeEventSource(m_pInterruptSrc);
    m_pInterruptSrc->release();
    m_pInterruptSrc = NULL;

    return true;
}
示例#14
0
bool BrcmPatchRAM::start(IOService *provider)
{
    DebugLog("start\n");

    if (!super::start(provider))
        return false;

    // place version/build info in ioreg properties RM,Build and RM,Version
    char buf[128];
    snprintf(buf, sizeof(buf), "%s %s", OSKextGetCurrentIdentifier(), OSKextGetCurrentVersionString());
    setProperty("RM,Version", buf);
#ifdef DEBUG
    setProperty("RM,Build", "Debug-" LOGNAME);
#else
    setProperty("RM,Build", "Release-" LOGNAME);
#endif

   // add interrupt source for delayed actions...
    IOWorkLoop* workLoop = getWorkLoop();
    if (!workLoop)
        return false;
    mWorkSource = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventAction, this, &BrcmPatchRAM::processWorkQueue));
    if (!mWorkSource)
        return false;
    workLoop->addEventSource(mWorkSource);
    mWorkPending = 0;

    // add timer for firmware load in the case no re-probe after wake
    mTimer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &BrcmPatchRAM::onTimerEvent));
    if (!mTimer)
    {
        workLoop->removeEventSource(mWorkSource);
        mWorkSource->release();
        mWorkSource = NULL;
        return false;
    }
    workLoop->addEventSource(mTimer);

    // register for power state notifications
    PMinit();
    registerPowerDriver(this, myTwoStates, 2);
    provider->joinPMtree(this);
    
    return true;
}
// Shut down the driver
void WirelessHIDDevice::handleStop(IOService *provider)
{
    WirelessDevice *device = OSDynamicCast(WirelessDevice, provider);

    if (device != NULL)
        device->RegisterWatcher(NULL, NULL, NULL);

    if (serialTimer != NULL) {
        serialTimer->cancelTimeout();
        IOWorkLoop *workloop = getWorkLoop();
        if (workloop != NULL)
            workloop->removeEventSource(serialTimer);
        serialTimer->release();
        serialTimer = NULL;
    }
    
    super::handleStop(provider);
}
void ACPIBacklightPanel::stop( IOService * provider )
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);

    IOWorkLoop* workLoop = getWorkLoop();
    if (workLoop)
    {
        if (_workSource)
        {
            workLoop->removeEventSource(_workSource);
            _workSource->release();
            _workSource = NULL;
        }
        if (_smoothTimer)
        {
            workLoop->removeEventSource(_smoothTimer);
            _smoothTimer->release();
            _smoothTimer = NULL;
        }
        if (_cmdGate)
        {
            workLoop->removeEventSource(_cmdGate);
            _cmdGate->release();
            _cmdGate = NULL;
        }
    }
    _extended = false;

    if (_lock)
    {
        IORecursiveLockFree(_lock);
        _lock = NULL;
    }

#if 0
    OSSafeReleaseNULL(_provider);
#endif

    _backlightHandler = NULL;

    super::stop(provider);
}
示例#17
0
IOWorkLoop *
IOWorkLoop::workLoopWithOptions(IOOptionBits options)
{
    IOWorkLoop *me = new IOWorkLoop;

    if (me && options) {
	me->reserved = IONew(ExpansionData, 1);
	if (!me->reserved) {
	    me->release();
	    return 0;
	}
	me->reserved->options = options;
    }

    if (me && !me->init()) {
        me->release();
        return 0;
    }

    return me;
}
void BatteryTracker::stop(IOService* provider)
{
    DEBUG_LOG("BatteryTracker::stop: entering stop\n");
    
    OSSafeReleaseNULL(m_pBatteryList);
    if (NULL != m_pLock)
    {
        IORecursiveLockFree(m_pLock);
        m_pLock = NULL;
    }
    if (m_pCmdGate)
    {
        IOWorkLoop* pWorkLoop = getWorkLoop();
        if (pWorkLoop)
            pWorkLoop->removeEventSource(m_pCmdGate);
        m_pCmdGate->release();
        m_pCmdGate = NULL;
    }
    
    IOService::stop(provider);
}
示例#19
0
IOReturn IOCommandGate::attemptAction(Action inAction,
                                      void *arg0, void *arg1,
                                      void *arg2, void *arg3)
{
    IOReturn res;
    IOWorkLoop * wl;

    if (!inAction)
        return kIOReturnBadArgument;
    if (!(wl = workLoop))
        return kIOReturnNotReady;

    // Try to close the gate if can't get return immediately.
    if (!wl->tryCloseGate())
        return kIOReturnCannotLock;

    // If the command gate is disabled then sleep until we get a wakeup
    if (!wl->onThread() && !enabled)
        res = kIOReturnNotPermitted;
    else {
		
        bool trace = ( gIOKitTrace & kIOTraceCommandGates ) ? true : false;
		
        if (trace)
            IOTimeStampStartConstant(IODBG_CMDQ(IOCMDQ_ACTION),
				     VM_KERNEL_UNSLIDE(inAction), (uintptr_t) owner);
        
        IOStatisticsActionCall();
        
        res = (*inAction)(owner, arg0, arg1, arg2, arg3);
		
        if (trace)
            IOTimeStampEndConstant(IODBG_CMDQ(IOCMDQ_ACTION),
				   VM_KERNEL_UNSLIDE(inAction), (uintptr_t) owner);
    }

    wl->openGate();

    return res;
}
示例#20
0
bool org_virtualbox_VBoxGuest::setupVmmDevInterrupts(IOService *pProvider)
{
    IOWorkLoop *pWorkLoop = getWorkLoop();
    if (!pWorkLoop)
        return false;

    m_pInterruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(this,
                                                                               &vgdrvDarwinDeferredIrqHandler,
                                                                               &vgdrvDarwinDirectIrqHandler,
                                                                               pProvider);
    IOReturn rc = pWorkLoop->addEventSource(m_pInterruptSrc);
    if (rc == kIOReturnSuccess)
    {
        m_pInterruptSrc->enable();
        return true;
    }

    m_pInterruptSrc->disable();
    m_pInterruptSrc->release();
    m_pInterruptSrc = NULL;
    return false;
}
// Start up the driver
bool WirelessHIDDevice::handleStart(IOService *provider)
{
    WirelessDevice *device;
    IOWorkLoop *workloop;
    
    if (!super::handleStart(provider))
        goto fail;

    device = OSDynamicCast(WirelessDevice, provider);
    if (device == NULL)
        goto fail;
    
    serialTimerCount = 0;
    
	serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper);
	if (serialTimer == NULL)
	{
		IOLog("start - failed to create timer for chatpad\n");
		goto fail;
	}
    workloop = getWorkLoop();
	if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess))
	{
		IOLog("start - failed to connect timer for chatpad\n");
		goto fail;
	}
    
    device->RegisterWatcher(this, _receivedData, NULL);
    
    device->SendPacket(weirdStart, sizeof(weirdStart));

    serialTimer->setTimeoutMS(1000);

    return true;
    
fail:
    return false;
}
void AppleSmartBatteryManager::stop(IOService *provider)
{
	DEBUG_LOG("AppleSmartBatteryManager::stop: called\n");
	
    fBattery->detach(this);
    
    fBattery->free();
    fBattery->stop(this);
    fBattery->terminate();
    fBattery = NULL;
    
    IOWorkLoop *wl = getWorkLoop();
    if (wl) {
        wl->removeEventSource(fBatteryGate);
    }

    fBatteryGate->free();
    fBatteryGate = NULL;
    
	PMstop();
    
    super::stop(provider);
}
示例#23
0
void IrDAComm::free()
{
    IOWorkLoop *workloop;
    
    XTRACE(kLogFree, 0, this);
    
    this->Stop();       // make sure we're stopped before releasing memory

    if (fDriver) {
	workloop = fDriver->getWorkLoop();
	if (workloop) {
	    if (fGate)
		workloop->removeEventSource(fGate);
	    //if (fTimerSrc)
	    //  workloop->removeEventSource(fTimerSrc);
	}
    }

#define FREE(x) { if (x) { (x)->release(); x = nil; }}

    FREE(fGate);
    FREE(fTimer);
    FREE(fIrComm);          // free the ircomm object before the rest of irda ...
    FREE(fIrDA);
    
#undef FREE

#define THREAD_FREE(x) do { if (x) {               \
			    thread_call_cancel(x); \
			    thread_call_free(x);   \
			    x = NULL; } } while(0)
    
    THREAD_FREE(fStop_thread);
#undef THREAD_FREE
    
    super::free();      // we're done, call super
}
示例#24
0
// Timeout handler function. This function is called by the kernel when
// the timeout interval expires.
//
void IOTimerEventSource::timeout(void *self)
{
    IOTimerEventSource *me = (IOTimerEventSource *) self;

    IOStatisticsTimeout();

    if (me->enabled && me->action)
    {
        IOWorkLoop *
        wl = me->workLoop;
        if (wl)
        {
            Action doit;
            wl->closeGate();
            IOStatisticsCloseGate();
            doit = (Action) me->action;
            if (doit && me->enabled && AbsoluteTime_to_scalar(&me->abstime))
            {
            	bool    trace = (gIOKitTrace & kIOTraceTimers) ? true : false;
            	
            	if (trace)
                	IOTimeStampStartConstant(IODBG_TIMES(IOTIMES_ACTION),
											 (uintptr_t) doit, (uintptr_t) me->owner);
				
                (*doit)(me->owner, me);
#if CONFIG_DTRACE
		DTRACE_TMR3(iotescallout__expire, Action, doit, OSObject, me->owner, void, me->workLoop);
#endif
                
				if (trace)
                	IOTimeStampEndConstant(IODBG_TIMES(IOTIMES_ACTION),
										   (uintptr_t) doit, (uintptr_t) me->owner);
            }
            IOStatisticsOpenGate();
            wl->openGate();
        }
void ApplePS2Mouse::stop(IOService * provider)
{
  //
  // The driver has been instructed to stop.  Note that we must break all
  // connections to other service objects now (ie. no registered actions,
  // no pointers and retains to objects, etc), if any.
  //

  assert(_device == provider);

  //
  // Disable the mouse itself, so that it may stop reporting mouse events.
  //

  setMouseEnable(false);

  // free up the command gate
  IOWorkLoop* pWorkLoop = getWorkLoop();
  if (pWorkLoop)
  {
    if (_cmdGate)
    {
      pWorkLoop->removeEventSource(_cmdGate);
      _cmdGate->release();
      _cmdGate = 0;
    }
    if (_buttonTimer)
    {
      pWorkLoop->removeEventSource(_buttonTimer);
      _buttonTimer->release();
      _buttonTimer = 0;
    }
  }
    
  //
  // Uninstall the interrupt handler.
  //

  if ( _interruptHandlerInstalled )  _device->uninstallInterruptAction();
  _interruptHandlerInstalled = false;

  //
  // Uninstall the power control handler.
  //

  if ( _powerControlHandlerInstalled ) _device->uninstallPowerControlAction();
  _powerControlHandlerInstalled = false;

  //
  // Uinstall message handler.
  //
  if (_messageHandlerInstalled)
  {
    _device->uninstallMessageAction();
    _messageHandlerInstalled = false;
  }
    
  //
  // Release the pointer to the provider object.
  //

  OSSafeReleaseNULL(_device);;

  super::stop(provider);
}
bool ApplePS2Mouse::start(IOService * provider)
{ 
  DEBUG_LOG("%s::start called\n", getName());
    
  //
  // The driver has been instructed to start. This is called after a
  // successful probe and match.
  //

  if (!super::start(provider))
      return false;

  //
  // Maintain a pointer to and retain the provider object.
  //

  _device = (ApplePS2MouseDevice *)provider;
  _device->retain();

  //
  // Setup workloop with command gate for thread syncronization...
  //
  IOWorkLoop* pWorkLoop = getWorkLoop();
  _cmdGate = IOCommandGate::commandGate(this);
  if (!pWorkLoop || !_cmdGate)
  {
    _device->release();
    return false;
  }
  pWorkLoop->addEventSource(_cmdGate);
    
  //
  // Setup button timer event source
  //
  _buttonTimer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ApplePS2Mouse::onButtonTimer));
  if (_buttonTimer)
      pWorkLoop->addEventSource(_buttonTimer);
    
  //
  // Lock the controller during initialization
  //
   
  _device->lock();
    
  //
  // Reset and enable the mouse.
  //

  resetMouse();

  //
  // Install our driver's interrupt handler, for asynchronous data delivery.
  //

  _device->installInterruptAction(this,
    OSMemberFunctionCast(PS2InterruptAction, this, &ApplePS2Mouse::interruptOccurred),
    OSMemberFunctionCast(PS2PacketAction, this, &ApplePS2Mouse::packetReady));
  _interruptHandlerInstalled = true;

  // now safe to allow other threads
  _device->unlock();
    
  //
  // Install our power control handler.
  //

  _device->installPowerControlAction( this,OSMemberFunctionCast
           (PS2PowerControlAction,this, &ApplePS2Mouse::setDevicePowerState) );
  _powerControlHandlerInstalled = true;

  //
  // Install message hook for keyboard to trackpad communication
  //
  
  if (actliketrackpad)
  {
    _device->installMessageAction( this,
                                  OSMemberFunctionCast(PS2MessageAction, this, &ApplePS2Mouse::receiveMessage));
    _messageHandlerInstalled = true;
  }
    
  return true;
}
bool AppleSmartBatteryManager::start(IOService *provider)
{
    DEBUG_LOG("AppleSmartBatteryManager::start: called\n");
    
    fProvider = OSDynamicCast(IOACPIPlatformDevice, provider);

    if (!fProvider || !super::start(provider)) {
        return false;
    }

    IOWorkLoop *wl = getWorkLoop();
    if (!wl) {
        return false;
    }

    // Join power management so that we can get a notification early during
    // wakeup to re-sample our battery data. We don't actually power manage
    // any devices.
	
	PMinit();
    registerPowerDriver(this, myTwoStates, 2);
    provider->joinPMtree(this);

    //rehabman: updated version
	IOLog("AppleSmartBatteryManager: Version 1.41 starting\n");

	int value = getPlatform()->numBatteriesSupported();
	DEBUG_LOG("AppleSmartBatteryManager: Battery Supported Count(s) %d.\n", value);

    // TODO: Create battery array to hold battery objects if more than one battery in the system
    
	if (value > 1) 
    { 
		if (kIOReturnSuccess == fProvider->evaluateInteger("_STA", &fBatterySTA)) {
			if (fBatterySTA & BATTERY_PRESENT) {
				goto populateBattery;
			} else {
				goto skipBattery;
			}
		}
	}

populateBattery:

	fBattery = AppleSmartBattery::smartBattery();

	if(!fBattery) 
		return false;

	fBattery->attach(this);

	fBattery->start(this);

    // Command gate for ACPIBatteryManager
    fManagerGate = IOCommandGate::commandGate(this);
    if (!fManagerGate) {
        return false;
    }
    wl->addEventSource(fManagerGate);

    // Command gate for ACPIBattery
    fBatteryGate = IOCommandGate::commandGate(fBattery);
    if (!fBatteryGate) {
        return false;
    }
    wl->addEventSource(fBatteryGate);

	fBattery->registerService(0);

skipBattery:

    this->setName("AppleSmartBatteryManager");
	this->registerService(0);

    return true;
}
bool IOFireWireSBP2LUN::attach(IOService *provider)
{
	IOReturn status = kIOReturnSuccess;
	
	// init fields
	fProviderTarget = NULL;
	fGate 			= NULL;
	fLUNumber 		= 0;
	fORBSet 		= NULL;
	fORBSetIterator = NULL;
	
    FWKLOG( ( "IOFireWireSBP2LUN<%p> : attach\n", this ) );
	
	//
	// attach to provider
	//
	
	if( status == kIOReturnSuccess )
	{
		fProviderTarget = OSDynamicCast( IOFireWireSBP2Target, provider );
		if( !fProviderTarget )
			status = kIOReturnError;
	}
	
	if( status == kIOReturnSuccess )
	{
		fProviderTarget->retain();
		if( !IOService::attach(provider) )
        	status = kIOReturnError;
	}

#if FWDIAGNOSTICS
	
	if( gDiagnostics_Symbol == NULL )
		gDiagnostics_Symbol = OSSymbol::withCString("SBP2 Diagnostics");

	fDiagnostics = IOFireWireSBP2Diagnostics::createDiagnostics();
	if( fDiagnostics )
	{
		setProperty( gDiagnostics_Symbol, fDiagnostics );
	}
	
#endif
	
	//
	// get lun number
	//
	
	if( status == kIOReturnSuccess )
	{
		OSObject *prop;

		// read lun number from registry		
		prop = getProperty( gIOUnit_Symbol );
		fLUNumber = ((OSNumber*)prop)->unsigned32BitValue();
	}
	
    //
    // create login set
    //
    
	if( status == kIOReturnSuccess )
	{
		fLoginSet = OSSet::withCapacity(1);
		if( fLoginSet == NULL )
			status = kIOReturnNoMemory;
	}
	
	if( status == kIOReturnSuccess )
	{
		if( fLoginSet )
            fLoginSetIterator = OSCollectionIterator::withCollection( fLoginSet );
	}
    
    
	//
	// create management orb set
	//
	
	if( status == kIOReturnSuccess )
	{
		fORBSet = OSSet::withCapacity(1);
		if( fORBSet == NULL )
			status = kIOReturnNoMemory;
	}
	
	if( status == kIOReturnSuccess )
	{
		if( fORBSet )
            fORBSetIterator = OSCollectionIterator::withCollection( fORBSet );
	}
	
	//
	// set up command gate
	//
	
	IOWorkLoop * workLoop = NULL;
	if( status == kIOReturnSuccess )
	{
		workLoop = getWorkLoop();
		if( !workLoop ) 
			status = kIOReturnNoResources;
	}
	
	if( status == kIOReturnSuccess )
	{
		fGate = IOCommandGate::commandGate( this );
		if( !fGate )
			status = kIOReturnNoMemory;
	}
	
	if( status == kIOReturnSuccess )
	{
		workLoop->retain();
		workLoop->addEventSource( fGate );
	}
	
    return (status == kIOReturnSuccess);
}
bool Xbox360Peripheral::start(IOService *provider)
{
    const IOUSBConfigurationDescriptor *cd;
    IOUSBFindInterfaceRequest intf;
    IOUSBFindEndpointRequest pipe;
    XBOX360_OUT_LED led;
    IOWorkLoop *workloop = NULL;
    /*
     * Xbox One controller init packets.
     * The Rock Candy Xbox One controller requires more than just 0x05
     * Minimum required packets unknown.
     */
    UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 };
    UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 };
    UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 };
    UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 };
    
    if (!super::start(provider))
		return false;
    // Get device
    device=OSDynamicCast(IOUSBDevice,provider);
    if(device==NULL) {
        IOLog("start - invalid provider\n");
        goto fail;
    }
    // Check for configurations
    if(device->GetNumConfigurations()<1) {
        device=NULL;
        IOLog("start - device has no configurations!\n");
        goto fail;
    }
    // Set configuration
    cd=device->GetFullConfigurationDescriptor(0);
    if(cd==NULL) {
        device=NULL;
        IOLog("start - couldn't get configuration descriptor\n");
        goto fail;
    }
    // Open
    if(!device->open(this)) {
        device=NULL;
        IOLog("start - unable to open device\n");
        goto fail;
    }
    if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) {
        IOLog("start - unable to set configuration\n");
        goto fail;
    }
    // Get release
    {
        UInt16 release = device->GetDeviceRelease();
        switch (release) {
            default:
                IOLog("Unknown device release %.4x\n", release);
                // fall through
            case 0x0110:
                chatpadInit[0] = 0x01;
                chatpadInit[1] = 0x02;
                break;
            case 0x0114:
                chatpadInit[0] = 0x09;
                chatpadInit[1] = 0x00;
                break;
        }
    }
    // Find correct interface
    controllerType = Xbox360;
    intf.bInterfaceClass=kIOUSBFindInterfaceDontCare;
    intf.bInterfaceSubClass=93;
    intf.bInterfaceProtocol=1;
    intf.bAlternateSetting=kIOUSBFindInterfaceDontCare;
    interface=device->FindNextInterface(NULL,&intf);
    if(interface==NULL) {
        // Find correct interface, Xbox original
        intf.bInterfaceClass=kIOUSBFindInterfaceDontCare;
        intf.bInterfaceSubClass=66;
        intf.bInterfaceProtocol=0;
        intf.bAlternateSetting=kIOUSBFindInterfaceDontCare;
        interface=device->FindNextInterface(NULL,&intf);
        if(interface==NULL) {
            // Find correct interface, Xbox One
            intf.bInterfaceClass=255;
            intf.bInterfaceSubClass=71;
            intf.bInterfaceProtocol=208;
            intf.bAlternateSetting=kIOUSBFindInterfaceDontCare;
            interface=device->FindNextInterface(NULL, &intf);
            if(interface==NULL)
            {
                IOLog("start - unable to find the interface\n");
                goto fail;
            }
            controllerType = XboxOne;
            goto interfacefound;
        }
        controllerType = XboxOriginal;
        goto interfacefound;
    }
interfacefound:
    interface->open(this);
    // Find pipes
    pipe.direction=kUSBIn;
    pipe.interval=0;
    pipe.type=kUSBInterrupt;
    pipe.maxPacketSize=0;
    inPipe=interface->FindNextPipe(NULL,&pipe);
    if(inPipe==NULL) {
        IOLog("start - unable to find in pipe\n");
        goto fail;
    }
    inPipe->retain();
    pipe.direction=kUSBOut;
    outPipe=interface->FindNextPipe(NULL,&pipe);
    if(outPipe==NULL) {
        IOLog("start - unable to find out pipe\n");
        goto fail;
    }
    outPipe->retain();
    // Get a buffer
    inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe));
    if(inBuffer==NULL) {
        IOLog("start - failed to allocate input buffer\n");
        goto fail;
    }
	// Find chatpad interface
	intf.bInterfaceClass = kIOUSBFindInterfaceDontCare;
	intf.bInterfaceSubClass = 93;
	intf.bInterfaceProtocol = 2;
	intf.bAlternateSetting = kIOUSBFindInterfaceDontCare;
	serialIn = device->FindNextInterface(NULL, &intf);
	if (serialIn == NULL) {
		IOLog("start - unable to find chatpad interface\n");
        goto nochat;
    }
	serialIn->open(this);
	// Find chatpad pipe
	pipe.direction = kUSBIn;
	pipe.interval = 0;
	pipe.type = kUSBInterrupt;
	pipe.maxPacketSize = 0;
	serialInPipe = serialIn->FindNextPipe(NULL, &pipe);
	if (serialInPipe == NULL)
	{
		IOLog("start - unable to find chatpad in pipe\n");
		goto fail;
	}
	serialInPipe->retain();
	// Get a buffer for the chatpad
	serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe));
	if (serialInBuffer == NULL)
	{
		IOLog("start - failed to allocate input buffer for chatpad\n");
		goto fail;
	}
	// Create timer for chatpad
	serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper);
	if (serialTimer == NULL)
	{
		IOLog("start - failed to create timer for chatpad\n");
		goto fail;
	}
    workloop = getWorkLoop();
	if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess))
	{
		IOLog("start - failed to connect timer for chatpad\n");
		goto fail;
	}
	// Configure ChatPad
	// Send 'configuration'
	SendInit(0xa30c, 0x4423);
	SendInit(0x2344, 0x7f03);
	SendInit(0x5839, 0x6832);
	// Set 'switch'
    if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) {
        // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX
        //goto fail;
	}
	// Begin toggle
	serialHeard = false;
	serialActive = false;
	serialToggle = false;
	serialResetCount = 0;
	serialTimerState = tsToggle;
	serialTimer->setTimeoutMS(1000);
    // Begin reading
    if (!QueueSerialRead())
        goto fail;
nochat:
    if (!QueueRead())
		goto fail;
    if (controllerType == XboxOne) {
        QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst));
        QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond));
        QueueWrite(&xoneInitThird, sizeof(xoneInitThird));
        QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth));
    } else {
        // Disable LED
        Xbox360_Prepare(led,outLed);
        led.pattern=ledOff;
        QueueWrite(&led,sizeof(led));
    }
    
    // Done
	PadConnect();
	registerService();
    return true;
fail:
    ReleaseAll();
    return false;
}
示例#30
0
bool
MolEnet::start( IOService * provider )
{
	IOPhysicalAddress tx_phys, rx_phys;
	IOPhysicalAddress tx_of_phys, rx_of_phys;
	int i, result;

	if( !super::start(provider) )
		return false;

	if( OSI_Enet2Open() ) {
		is_open = 1;
		return false;
	}
	
	//transmitQueue = OSDynamicCast( IOGatedOutputQueue, getOutputQueue() );
	transmitQueue = OSDynamicCast( IOBasicOutputQueue, getOutputQueue() );
	if( !transmitQueue ) {
		printm("MolEnet: output queue initialization failed\n");
		return false;
	}
	transmitQueue->retain();

	// Allocate a IOMbufBigMemoryCursor instance. Currently, the maximum
	// number of segments is set to 2. The maximum length for each segment
	// is set to the maximum ethernet frame size (plus padding).

	txMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	rxMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	if( !txMBufCursor || !rxMBufCursor ) {
		printm("MolEnet: IOMbufBigMemoryCursor allocation failure\n");
		return false;
	}

	// Get a reference to the IOWorkLoop in our superclass.
	IOWorkLoop * myWorkLoop = getWorkLoop();
	assert(myWorkLoop);

	// Allocate a IOInterruptEventSources.
	_irq = IOInterruptEventSource::interruptEventSource( this, 
				     (IOInterruptEventAction)&MolEnet::rxIRQ, provider, 0);
	
        if( !_irq || (myWorkLoop->addEventSource(_irq) != kIOReturnSuccess )) {
		printm("MolEnet: _irq init failure\n");
		return false;
	}

	// Allocate the ring descriptors
	rx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * RX_NUM_EL * sizeof(enet2_ring_t), 
						     sizeof(enet2_ring_t), &rx_phys );
	tx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * TX_NUM_EL * sizeof(enet2_ring_t),
						     sizeof(enet2_ring_t), &tx_phys );		
	if( !rx_ring || !tx_ring )
		return false;

	rx_of_ring = rx_ring + RX_NUM_EL;
	tx_of_ring = tx_ring + TX_NUM_EL;
	rx_of_phys = rx_phys + sizeof(enet2_ring_t) * RX_NUM_EL;
	tx_of_phys = tx_phys + sizeof(enet2_ring_t) * TX_NUM_EL;

	// Allocate receive buffers
	for( i=0; i<RX_NUM_EL; i++ ) {
		if( !(rxMBuf[i]=allocatePacket( NETWORK_BUFSIZE )) ) {
			printm("MolEnet: packet allocation failed\n");
			return false;
		}
		// reserve 2 bytes before the actual packet
		rxMBuf[i]->m_data += 2;
		rxMBuf[i]->m_len -= 2;
	}

	OSI_Enet2Cntrl( kEnet2Reset );
	result = OSI_Enet2RingSetup( kEnet2SetupRXRing, rx_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXRing, tx_phys, TX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupRXOverflowRing, rx_of_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXOverflowRing, tx_of_phys, TX_NUM_EL );
	if( result )
		return false;

	if( !resetAndEnable(false) )
		return false;

	// Create a table of supported media types.
	if( !createMediumTables() )
		return false;

	// Attach an IOEthernetInterface client.
	if( !attachInterface( (IONetworkInterface**)&networkInterface, false ) )
		return false;

	// Ready to service interface requests.
	networkInterface->registerService();

	printm("Ethernet driver 1.1\n");
	return true;
}