Example #1
0
bool IOWorkLoop::init()
{
    // The super init and gateLock allocation MUST be done first.
    if ( !super::init() )
        return false;
	
	// Allocate our ExpansionData if it hasn't been allocated already.
	if ( !reserved )
	{
		reserved = IONew(ExpansionData,1);
		if ( !reserved )
			return false;
		
		bzero(reserved,sizeof(ExpansionData));
	}
	
#if DEBUG
	OSBacktrace ( reserved->allocationBacktrace, sizeof ( reserved->allocationBacktrace ) / sizeof ( reserved->allocationBacktrace[0] ) );
#endif
	
    if ( gateLock == NULL ) {
        if ( !( gateLock = IORecursiveLockAlloc()) )
            return false;
    }
	
    if ( workToDoLock == NULL ) {
        if ( !(workToDoLock = IOSimpleLockAlloc()) )
            return false;
        IOSimpleLockInit(workToDoLock);
        workToDo = false;
    }

    if (!reserved) {
        reserved = IONew(ExpansionData, 1);
        reserved->options = 0;
    }
	
    IOStatisticsRegisterCounter();

    if ( controlG == NULL ) {
        controlG = IOCommandGate::commandGate(
            this,
            OSMemberFunctionCast(
                IOCommandGate::Action,
                this,
                &IOWorkLoop::_maintRequest));

        if ( !controlG )
            return false;
        // Point the controlGate at the workLoop.  Usually addEventSource
        // does this automatically.  The problem is in this case addEventSource
        // uses the control gate and it has to be bootstrapped.
        controlG->setWorkLoop(this);
        if (addEventSource(controlG) != kIOReturnSuccess)
            return false;
    }

    if ( workThread == NULL ) {
        thread_continue_t cptr = OSMemberFunctionCast(
            thread_continue_t,
            this,
            &IOWorkLoop::threadMain);
        if (KERN_SUCCESS != kernel_thread_start(cptr, this, &workThread))
            return false;
    }

    (void) thread_set_tag(workThread, THREAD_TAG_IOWORKLOOP);
    return true;
}
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;
}
Example #3
0
bool darwin_iwi4965::start(IOService *provider)
{
	UInt16	reg;
//linking the kext control clone to the driver:
		clone=this;
		firstifup=0;
	do {
				
		if ( super::start(provider) == 0) {
			IOLog("%s ERR: super::start failed\n", getName());
			break;
		}
			
		if ( (fPCIDevice = OSDynamicCast(IOPCIDevice, provider)) == 0) {
			IOLog("%s ERR: fPCIDevice == 0 :(\n", getName());
			break;
		}

		fPCIDevice->retain();
		
		if (fPCIDevice->open(this) == 0) {
			IOLog("%s ERR: fPCIDevice->open(this) failed\n", getName());
			break;
		}
		
		// Request domain power.
        	// Without this, the PCIDevice may be in state 0, and the
        	// PCI config space may be invalid if the machine has been
       		// sleeping.
		if (fPCIDevice->requestPowerDomainState(kIOPMPowerOn, 
			(IOPowerConnection *) getParentEntry(gIOPowerPlane),
			IOPMLowestState ) != IOPMNoErr) {
				IOLog("%s Power thingi failed\n", getName());
				break;
       		}
		
		UInt16 reg16;
		reg16 = fPCIDevice->configRead16(kIOPCIConfigCommand);
		reg16 |= (kIOPCICommandBusMaster      |
				  kIOPCICommandMemorySpace    |
				  kIOPCICommandMemWrInvalidate);
		reg16 &= ~kIOPCICommandIOSpace;  // disable I/O space
		fPCIDevice->configWrite16(kIOPCIConfigCommand,reg16);
		
		irqNumber = fPCIDevice->configRead8(kIOPCIConfigInterruptLine);
		vendorID = fPCIDevice->configRead16(kIOPCIConfigVendorID);
		deviceID = fPCIDevice->configRead16(kIOPCIConfigDeviceID);		
		pciReg = fPCIDevice->configRead16(kIOPCIConfigRevisionID);

  		map = fPCIDevice->mapDeviceMemoryWithRegister(kIOPCIConfigBaseAddress0, kIOMapInhibitCache);
  		if (map == 0) {
			IOLog("%s map is zero\n", getName());
			break;
		}
		ioBase = map->getPhysicalAddress();
		memBase = (UInt16 *)map->getVirtualAddress();
		memDes = map->getMemoryDescriptor();
		mem = fPCIDevice->getDeviceMemoryWithRegister(kIOPCIConfigBaseAddress0);
		
		memDes->initWithPhysicalAddress(ioBase, map->getLength(), kIODirectionOutIn);
					 
		/* We disable the RETRY_TIMEOUT register (0x41) to keep
		 * PCI Tx retries from interfering with C3 CPU state */
		reg = fPCIDevice->configRead16(0x40);
		if((reg & 0x0000ff00) != 0)
			fPCIDevice->configWrite16(0x40, reg & 0xffff00ff);
			

		IOLog("%s iomemory length: 0x%x @ 0x%x\n", getName(), map->getLength(), ioBase);
		IOLog("%s virt: 0x%x physical: 0x%x\n", getName(), memBase, ioBase);
		IOLog("%s IRQ: %d, Vendor ID: %04x, Product ID: %04x\n", getName(), irqNumber, vendorID, deviceID);
		
		fWorkLoop = (IOWorkLoop *) getWorkLoop();
		if (!fWorkLoop) {
			IOLog("%s ERR: start - getWorkLoop failed\n", getName());
			break;
		}
		fInterruptSrc = IOInterruptEventSource::interruptEventSource(
			this, (IOInterruptEventAction) &darwin_iwi4965::interruptOccurred,
			provider);
		if(!fInterruptSrc || (fWorkLoop->addEventSource(fInterruptSrc) != kIOReturnSuccess)) {
			IOLog("%s fInterruptSrc error\n", getName());
			break;;
		}
		// 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.
		fInterruptSrc->enable();
		//mutex=IOLockAlloc();
		
		fTransmitQueue = createOutputQueue();
		if (fTransmitQueue == NULL)
		{
			IWI_ERR("ERR: getOutputQueue()\n");
			break;
		}
		fTransmitQueue->setCapacity(1024);
		//priv=NULL;
		iwl_pci_probe();
		if (!priv) break;
		iwl_hw_nic_init(priv);
		iwl_hw_nic_reset(priv);
		
		if (attachInterface((IONetworkInterface **) &fNetif, false) == false) {
			IOLog("%s attach failed\n", getName());
			break;
		}
		setProperty(kIOMinPacketSize,12);
		setProperty(kIOMaxPacketSize, IWL_RX_BUF_SIZE);
		//setProperty(kIOFeatures, kIONetworkFeatureNoBSDWait|kIONetworkFeatureSoftwareVlan);
	
		fNetif->registerOutputHandler(this,getOutputHandler());
		
		fNetif->registerService();
		registerService();
		
		mediumDict = OSDictionary::withCapacity(MEDIUM_TYPE_INVALID + 1);
		addMediumType(kIOMediumIEEE80211None,  0,  MEDIUM_TYPE_NONE);
		addMediumType(kIOMediumIEEE80211Auto,  0,  MEDIUM_TYPE_AUTO);
		publishMediumDictionary(mediumDict);
		setCurrentMedium(mediumTable[MEDIUM_TYPE_AUTO]);
		setSelectedMedium(mediumTable[MEDIUM_TYPE_AUTO]);
		setLinkStatus(kIONetworkLinkValid, mediumTable[MEDIUM_TYPE_AUTO]);
		
		//kext control registration:
		//these functions registers the control which enables
		//the user to interact with the driver
		
		struct kern_ctl_reg		ep_ctl; // Initialize control
		kern_ctl_ref	kctlref;
		bzero(&ep_ctl, sizeof(ep_ctl));
		ep_ctl.ctl_id = 0; /* OLD STYLE: ep_ctl.ctl_id = kEPCommID; */
		ep_ctl.ctl_unit = 0;
		strcpy(ep_ctl.ctl_name,"insanelymac.iwidarwin.control");
		ep_ctl.ctl_flags = 0;
		ep_ctl.ctl_connect = ConnectClient;
		ep_ctl.ctl_disconnect = disconnectClient;
		ep_ctl.ctl_send = setSelectedNetwork;
		ep_ctl.ctl_setopt = configureConnection;
		ep_ctl.ctl_getopt = sendNetworkList;
		errno_t error = ctl_register(&ep_ctl, &kctlref);
		
		queue_te(12,OSMemberFunctionCast(thread_call_func_t,this,&darwin_iwi4965::check_firstup),NULL,NULL,false);
		queue_te(12,OSMemberFunctionCast(thread_call_func_t,this,&darwin_iwi4965::check_firstup),priv,1000,true);

		return true;			// end start successfully
	} while (false);
		
	//stop(provider);
	//free();
	return false;			// end start insuccessfully
}
Example #4
0
bool ACPIProbe::start(IOService * provider)
{
    ACPISensorsDebugLog("starting...");
    
	if (!super::start(provider))
        return false;
    
	if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) {
        ACPISensorsFatalLog("ACPI device not ready");
        return false;
    }

    profiles = OSDictionary::withCapacity(0);
    profileList = OSArray::withCapacity(0);

    OSObject *object = NULL;


    // Try to load configuration provided by ACPI device

        if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) {
            if (OSArray *list = OSDynamicCast(OSArray, object)) {
                for (unsigned int i = 0; i < list->getCount(); i++) {
                    if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) {
                        if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) {
                            if (OSArray *config = OSDynamicCast(OSArray, object)) {
                                if (config->getCount() > 4) {
                                    OSString *pName = OSDynamicCast(OSString, config->getObject(0));
                                    OSNumber *pInterval = OSDynamicCast(OSNumber, config->getObject(1));
                                    OSNumber *pTimeout = OSDynamicCast(OSNumber, config->getObject(2));
                                    OSNumber *pVerbose = OSDynamicCast(OSNumber, config->getObject(3));

                                    OSArray *pMethods = OSArray::withCapacity(config->getCount() - 4);

                                    for (unsigned int offset = 4; offset < config->getCount(); offset++) {
                                        if (OSString *methodName = OSDynamicCast(OSString, config->getObject(offset))) {
                                            pMethods->setObject(methodName);
                                        }
                                    }

                                    addProfile(pName, pMethods, pInterval, pTimeout, pVerbose);
                                }
                            }

                            OSSafeRelease(object);
                        }
                    }
                }

                OSSafeRelease(list);
            }

        }
        else {
            ACPISensorsErrorLog("profile definition table (LIST) not found");
        }

    // Try to load configuration from info.plist
    if (profiles->getCount() == 0) {
        if (OSDictionary *configuration = getConfigurationNode())
        {
            OSString *pName = OSDynamicCast(OSString, configuration->getObject("ProfileName"));
            OSNumber *pInterval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval"));
            OSNumber *pTimeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout"));
            OSBoolean *pVerboseBool = OSDynamicCast(OSBoolean, configuration->getObject("VerboseLog"));
            OSNumber *pVerbose = OSNumber::withNumber(pVerboseBool->getValue() ? 1 : 0, 8);
            OSArray *pMethods = OSDynamicCast(OSArray, configuration->getObject("MethodsToPoll"));

            addProfile(pName, pMethods, pInterval, pTimeout, pVerbose);
        }
    }

    if (this->profiles->getCount()) {

        // Parse active profile
        if (kIOReturnSuccess == acpiDevice->evaluateObject("ACTV", &object) && object) {
            if (OSString *method = OSDynamicCast(OSString, object)) {
                if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) {
                    if (OSArray *config = OSDynamicCast(OSArray, object)) {
                        if (config->getCount() > 4) {
                            if (OSString *profile = OSDynamicCast(OSString, config->getObject(0))) {
                                if (!(activeProfile = (ACPIProbeProfile *)profiles->getObject(profile))) {
                                    activeProfile = (ACPIProbeProfile *)profileList->getObject(0);
                                }
                            }
                        }
                    }

                    OSSafeRelease(object);
                }

                OSSafeRelease(method);
            }
        }

        // woorkloop
        if (!(workloop = getWorkLoop())) {
            HWSensorsFatalLog("Failed to obtain workloop");
            return false;
        }
        
        if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) {
            ACPISensorsFatalLog("failed to initialize timer event source");
            return false;
        }
        
        if (kIOReturnSuccess != workloop->addEventSource(timerEventSource))
        {
            ACPISensorsFatalLog("failed to add timer event source into workloop");
            return false;
        }
        
        timerEventSource->setTimeoutMS(100);
        
        //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : "");
    }

    // two power states - off and on
	static const IOPMPowerState powerStates[2] = {
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 }
    };

    // register interest in power state changes
	PMinit();
	provider->joinPMtree(this);
	registerPowerDriver(this, (IOPMPowerState *)powerStates, 2);
    
	registerService();
    
    ACPISensorsInfoLog("started");
    
	return true;
}
Example #5
0
bool LPCSensors::start(IOService *provider)
{
	if (!super::start(provider))
        return false;

    OSNumber *number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOHWMAddress));

    if (!number || !(address = number->unsigned16BitValue())) {
        HWSensorsFatalLog("wrong address provided");
        return false;
    }

    number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOControlPort));

    if (!number || !(port = number->unsigned8BitValue())) {
        HWSensorsFatalLog("wrong port provided");
        return false;
    }

    number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOModelValue));

    if (!number || !(model = number->unsigned16BitValue())) {
        HWSensorsFatalLog("wrong model provided");
        return false;
    }

    OSString *string = OSDynamicCast(OSString, provider->getProperty(kSuperIOModelName));

    if (!string || !(modelName = string->getCStringNoCopy())) {
        HWSensorsFatalLog("wrong model name provided");
        return false;
    }

    string = OSDynamicCast(OSString, provider->getProperty(kSuperIOVendorName));

    if (!string || !(vendorName = string->getCStringNoCopy())) {
        HWSensorsFatalLog("wrong vendor name provided");
        return false;
    }

    if (!initialize())
        return false;

    OSString *modelString = OSString::withCString(modelName);

	if (OSDictionary *configuration = getConfigurationNode(modelString))
    {
        addTemperatureSensors(configuration);
        addVoltageSensors(configuration);
        addTachometerSensors(configuration);
    }
    else HWSensorsWarningLog("no platform profile provided");

    OSSafeReleaseNULL(modelString);

    // woorkloop
    if (!(workloop = getWorkLoop())) {
        HWSensorsFatalLog("Failed to obtain workloop");
        return false;
    }

    if (!(timerEventSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &LPCSensors::woorkloopTimerEvent)))) {
        HWSensorsFatalLog("failed to initialize timer event source");
        return false;
    }

    if (kIOReturnSuccess != workloop->addEventSource(timerEventSource))
    {
        HWSensorsFatalLog("failed to add timer event source into workloop");
        return false;
    }

    // two power states - off and on
	static const IOPMPowerState powerStates[2] = {
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 }
    };

    // register interest in power state changes
	PMinit();
	provider->joinPMtree(this);
	registerPowerDriver(this, (IOPMPowerState *)powerStates, 2);

    registerService();

    HWSensorsInfoLog("started");

	return true;
}
Example #6
0
bool AtherosL1Ethernet::start(IOService *provider)
{
    DbgPrint("start()\n");

    at_adapter *adapter=&adapter_;
    
    if (!BASE::start(provider))
    {
        ErrPrint("Couldn't start BASE\n");
        return false;
    }

    adapter->pdev = OSDynamicCast(IOPCIDevice, provider);

    if (!adapter->pdev)
    {
        ErrPrint("Unable to cast provider\n");
        return false;
    }

    adapter->pdev->retain();
    adapter->pdev->open(this);

    //Adding Mac OS X PHY's
    mediumDict = OSDictionary::withCapacity(MEDIUM_INDEX_COUNT + 1);

    OSAddNetworkMedium(kIOMediumEthernetAuto, 0, MEDIUM_INDEX_AUTO);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionHalfDuplex, 10 * MBit, MEDIUM_INDEX_10HD);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionFullDuplex, 10 * MBit, MEDIUM_INDEX_10FD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionHalfDuplex, 100 * MBit, MEDIUM_INDEX_100HD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionFullDuplex, 100 * MBit, MEDIUM_INDEX_100FD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionHalfDuplex, 1000 * MBit, MEDIUM_INDEX_1000HD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionFullDuplex, 1000 * MBit, MEDIUM_INDEX_1000FD);
    
    if (!publishMediumDictionary(mediumDict)) return false;

    if (!atProbe()) //Fix false reporting int probe function
    {
        ErrPrint("Couldn't probe adapter\n");
        stop(provider);
        return false;
    }
    

    workLoop_ = getWorkLoop();
    if (!workLoop_)
    {
        ErrPrint("workLoop is not exists\n");
        stop(provider);
        return false;
    }

    transmitQueue_ = getOutputQueue();
    if (!transmitQueue_)
    {
        ErrPrint("transmitQueue is not exists\n");
        stop(provider);
        return false;
    }

    //Looking for MSI interrupt index
    int msi_index = -1;
    int intr_index = 0, intr_type = 0;
    IOReturn intr_ret;
    while (true)
    {
        intr_ret = provider->getInterruptType(intr_index, &intr_type);
        if (intr_ret != kIOReturnSuccess) break;
        if (intr_type & kIOInterruptTypePCIMessaged) msi_index = intr_index;
        intr_index++;
    }

    if (msi_index != -1)
    {
        DbgPrint("MSI interrupt index %d\n", msi_index);
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev, msi_index);
    }

    if (msi_index == -1 || intSource_ == NULL)
    {
        DbgPrint("MSI index was not found or MSI interrupt couldn't be enabled\n");
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev);
    }

    //Adding interrupt to our workloop event sources
    if (!intSource_ || workLoop_->addEventSource(intSource_) != kIOReturnSuccess)
    {
        if (!intSource_) ErrPrint("Couldn't create interrupt source\n");
        else ErrPrint("Couldn't attach interrupt source\n");
        stop(provider);
        return false;
    }

    //Attaching dynamic link layer
    if (!this->attachInterface(reinterpret_cast<IONetworkInterface **>(&netIface_)), false)
    {
        DbgPrint("Failed to attach data link layer\n");
        return false;
    }

    intSource_->enable();
    
    /* allocate Tx / RX descriptor resources */
    if (at_setup_ring_resources(adapter))
    {
        ErrPrint("Couldn't allocate ring descriptors\n");
        adapter->pdev->close(this);
        return kIOReturnError;
    }
    

    netIface_->registerService();
    adapter->pdev->close(this);
    return true;
}
Example #7
0
void net_habitue_device_SC101::doSubmitIO(outstanding_io *io)
{
  bool isWrite = (io->buffer->getDirection() == kIODirectionOut);
  UInt32 ioLen = (io->nblks * SECTOR_SIZE);
  mbuf_t m;

  retryResolve();
  
  if (isWrite)
  {
    KDEBUG("%p write %d %d (%d)", io, io->block, io->nblks, _outstandingCount);
    
    psan_put_t req;
    bzero(&req, sizeof(req));
    req.ctrl.cmd = PSAN_PUT;
    req.ctrl.seq = ((net_habitue_driver_SC101 *)getProvider())->getSequenceNumber();
    req.ctrl.len_power = POWER_OF_2(ioLen);
    req.sector = htonl(io->block);
    
    if (mbuf_allocpacket(MBUF_WAITOK, sizeof(req) + ioLen, NULL, &m) != 0)
      KINFO("mbuf_allocpacket failed!"); // TODO(iwade) handle

    if (mbuf_copyback(m, 0, sizeof(req), &req, MBUF_WAITOK) != 0)
      KINFO("mbuf_copyback failed!"); // TODO(iwade) handle
    
    if (!mbuf_buffer(io->buffer, 0, m, sizeof(req), ioLen))
      KINFO("mbuf_buffer failed"); // TODO(iwade) handle

    io->outstanding.seq = ntohs(req.ctrl.seq);
    io->outstanding.len = sizeof(psan_put_response_t);
    io->outstanding.cmd = PSAN_PUT_RESPONSE;
  }
  else
  {
    KDEBUG("%p read %d %d (%d)", io, io->block, io->nblks, _outstandingCount);
    
    psan_get_t req;
    bzero(&req, sizeof(req));
    req.ctrl.cmd = PSAN_GET;
    req.ctrl.seq = ((net_habitue_driver_SC101 *)getProvider())->getSequenceNumber();
    req.ctrl.len_power = POWER_OF_2(ioLen);
    req.sector = htonl(io->block);
    
    if (mbuf_allocpacket(MBUF_WAITOK, sizeof(req), NULL, &m) != 0)
      KINFO("mbuf_allocpacket failed!"); // TODO(iwade) handle

    if (mbuf_copyback(m, 0, sizeof(req), &req, MBUF_WAITOK) != 0)
      KINFO("mbuf_copyback failed!"); // TODO(iwade) handle
    
    io->outstanding.seq = ntohs(req.ctrl.seq);
    io->outstanding.len = sizeof(psan_get_response_t) + ioLen;
    io->outstanding.cmd = PSAN_GET_RESPONSE;
  }
  
  io->outstanding.packetHandler = OSMemberFunctionCast(PacketHandler, this, &net_habitue_device_SC101::handleAsyncIOPacket);
  io->outstanding.timeoutHandler = OSMemberFunctionCast(TimeoutHandler, this, &net_habitue_device_SC101::handleAsyncIOTimeout);
  io->outstanding.target = this;
  io->outstanding.ctx = io;
  io->outstanding.timeout_ms = io->timeout_ms;

  ((net_habitue_driver_SC101 *)getProvider())->sendPacket((sockaddr_in *)io->addr->getBytesNoCopy(), m, &io->outstanding);
}
Example #8
0
int VoodooI2CHIDDevice::initHIDDevice(I2CDevice *hid_device) {
    int ret;
    UInt16 hidRegister;
    
    ihid = (i2c_hid*)IOMalloc(sizeof(i2c_hid));
    
    ihid->client = hid_device;
    
    ret = i2c_hid_acpi_pdata(ihid);
    
    ihid->client = hid_device;
    
    
    hidRegister = ihid->pdata.hid_descriptor_address;
    
    ihid->wHIDDescRegister = (__le16)hidRegister;
    
    ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE);
    if (ret < 0)
        goto err;
    
    //ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
    //if(ret<0)
     //   goto err;
    
    
    ret = i2c_hid_fetch_hid_descriptor(ihid);
    if (ret < 0)
        goto err;
    
    setProperty("HIDDescLength", (UInt32)ihid->hdesc.wHIDDescLength, 32);
    setProperty("bcdVersion", (UInt32)ihid->hdesc.bcdVersion, 32);
    setProperty("ReportDescLength", (UInt32)ihid->hdesc.wReportDescLength, 32);
    setProperty("ReportDescRegister", (UInt32)ihid->hdesc.wReportDescRegister, 32);
    setProperty("InputRegister", (UInt32)ihid->hdesc.wInputRegister, 32);
    setProperty("MaxInputLength", (UInt32)ihid->hdesc.wMaxInputLength, 32);
    setProperty("OutputRegister", (UInt32)ihid->hdesc.wOutputRegister, 32);
    setProperty("MaxOutputLength", (UInt32)ihid->hdesc.wMaxOutputLength, 32);
    setProperty("CommandRegister", (UInt32)ihid->hdesc.wCommandRegister, 32);
    setProperty("DataRegister", (UInt32)ihid->hdesc.wDataRegister, 32);
    setProperty("vendorID", (UInt32)ihid->hdesc.wVendorID, 32);
    setProperty("productID", (UInt32)ihid->hdesc.wProductID, 32);
    setProperty("VersionID", (UInt32)ihid->hdesc.wVersionID, 32);
    
    
    hid_device->workLoop = (IOWorkLoop*)getWorkLoop();
    if(!hid_device->workLoop) {
        IOLog("%s::%s::Failed to get workloop\n", getName(), _controller->_dev->name);
        stop(this);
        return -1;
    }

    hid_device->workLoop->retain();

    /*
     hid_device->interruptSource = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventAction, this, &VoodooI2CHIDDevice::InterruptOccured), hid_device->provider);
     
     if (hid_device->workLoop->addEventSource(hid_device->interruptSource) != kIOReturnSuccess) {
         IOLog("%s::%s::Could not add interrupt source to workloop\n", getName(), _controller->_dev->name);
         stop(this);
         return -1;
     }
     
     hid_device->interruptSource->enable();
     */
    
    hid_device->timerSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &VoodooI2CHIDDevice::i2c_hid_get_input));
    if (!hid_device->timerSource){
        goto err;
    }
    
    hid_device->workLoop->addEventSource(hid_device->timerSource);
    hid_device->timerSource->setTimeoutMS(10);
     /*
     
     hid_device->commandGate = IOCommandGate::commandGate(this);
     
     if (!hid_device->commandGate || (_dev->workLoop->addEventSource(hid_device->commandGate) != kIOReturnSuccess)) {
     IOLog("%s::%s::Failed to open HID command gate\n", getName(), _dev->name);
     return -1;
     }
     */
    
    i2c_hid_get_report_descriptor(ihid);

    initialize_wrapper();
    registerService();
    
    return 0;
    
err:
    i2c_hid_free_buffers(ihid, HID_MIN_BUFFER_SIZE);
    IOFree(ihid, sizeof(i2c_hid));
    return ret;
}
 * 
 * Called by AppleSmartBatteryManagerUserClient
 */
IOReturn AppleSmartBatteryManager::performExternalTransactionGated( 
    void                    *arg0,
    void                    *arg1,
    void                    *arg2 __unused,
    void                    *arg3 __unused)
{
    IOSMBusTransaction      *trans = (IOSMBusTransaction *)arg0;
    IOReturn                *return_code = (IOReturn *)arg1;
    
    *return_code = fProvider->performTransaction(
                        trans,          /* transaction */
                        OSMemberFunctionCast( 
                            IOSMBusTransactionCompletion, /* completion */
                            this, &AppleSmartBatteryManager::transactionCompletion),                                
                        (OSObject *)this,       /* target */
                        (void *)trans);         /* ref */


    if(kIOReturnSuccess != *return_code)
        return kIOReturnSuccess;

    /* Sleep the caller's thread until the transaction completion returns */
    fManagerGate->commandSleep(trans, THREAD_UNINT);

    /* at this point our transaction is complete; return */
    
    return kIOReturnSuccess;
}
bool ApplePS2Keyboard::start(IOService * provider)
{
    OSBoolean *xml_swap_CAPSLOCK_CTRL;
    OSBoolean *xml_swap_ALT_WIN;
    OSBoolean *xml_use_right_modifier_into_HANGUL_HANJA;
    OSBoolean *xml_make_APP_into_RWIN;
    OSBoolean *xml_swap_GRAVE_EUROPE2;
    OSBoolean *xml_make_APP_into_AppleFN;
    
    //
    // The driver has been instructed to start.   This is called after a
    // successful attach.
    //

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

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

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


    //
    // Configure user preferences from Info.plist
    //

    xml_swap_CAPSLOCK_CTRL = OSDynamicCast( OSBoolean, getProperty("Swap capslock and left control"));
    if (xml_swap_CAPSLOCK_CTRL) {
        if ( xml_swap_CAPSLOCK_CTRL->getValue()) {
            char temp = _PS2ToADBMap[0x3a];
            _PS2ToADBMap[0x3a] = _PS2ToADBMap[0x1d];
            _PS2ToADBMap[0x1d] = temp;
        }
    }

    xml_swap_ALT_WIN = OSDynamicCast( OSBoolean, getProperty("Swap command and option"));
    if (xml_swap_ALT_WIN) {
        if ( xml_swap_ALT_WIN->getValue()) {
            char temp = _PS2ToADBMap[0x38];
            _PS2ToADBMap[0x38] = _PS2ToADBMap[0x15b];
            _PS2ToADBMap[0x15b] = temp;

            temp = _PS2ToADBMap[0x138];
            _PS2ToADBMap[0x138] = _PS2ToADBMap[0x15c];
            _PS2ToADBMap[0x15c] = temp;
        }
    }

    xml_use_right_modifier_into_HANGUL_HANJA = OSDynamicCast( \
            OSBoolean, getProperty("Make right modifier keys into Hangul and Hanja"));
    if (xml_use_right_modifier_into_HANGUL_HANJA) {
        if ( xml_use_right_modifier_into_HANGUL_HANJA->getValue()) {
            _PS2ToADBMap[0x138] = _PS2ToADBMap[0xf2];    // Right alt becomes Hangul
            _PS2ToADBMap[0x11d] = _PS2ToADBMap[0xf1];    // Right control becomes Hanja
        }
    }

    xml_make_APP_into_RWIN = OSDynamicCast( OSBoolean, getProperty("Make Application key into right windows"));
    if (xml_make_APP_into_RWIN) {
        if ( xml_make_APP_into_RWIN->getValue())
            _PS2ToADBMap[0x15d] = _PS2ToADBMap[0x15c];
    }

    // not implemented yet.
    // Apple Fn key works well, but no combined key action was made.
    xml_make_APP_into_AppleFN = OSDynamicCast( OSBoolean, getProperty("Make Application key into Apple Fn key"));
    if (xml_make_APP_into_AppleFN) {
        if ( xml_make_APP_into_AppleFN->getValue()) {
            _PS2ToADBMap[0x15d] = 0x3f;
        }
    }

    // ISO specific mapping to match ADB keyboards
    // This should really be done in the keymaps.
    xml_swap_GRAVE_EUROPE2 = OSDynamicCast( OSBoolean, getProperty("Use ISO layout keyboard"));
    if (xml_swap_GRAVE_EUROPE2) {
        if ( xml_swap_GRAVE_EUROPE2->getValue()) {
            char temp = _PS2ToADBMap[0x29];             //Grave '~'
            _PS2ToADBMap[0x29] = _PS2ToADBMap[0x56];    //Europe2 '¤º'
            _PS2ToADBMap[0x56] = temp;
        }
    }
    
    // now load PS2 -> PS2 configuration data
    
    OSArray* pArray = OSDynamicCast(OSArray, getProperty("Custom PS2 Map"));
    if (NULL != pArray)
    {
        for (int i = 0; i < pArray->getCount(); i++)
        {
            OSString* pString = OSDynamicCast(OSString, pArray->getObject(i));
            if (NULL == pString)
                continue;
            const char* psz = pString->getCStringNoCopy();
            // check for comment
            if (';' == *psz)
                continue;
            // otherwise, try to parse it
            UInt16 scanIn, scanOut;
            if (!parseRemap(psz, scanIn, scanOut))
            {
                IOLog("VoodooPS2Keyboard: invalid custom PS2 map entry: \"%s\"\n", psz);
                continue;
            }
            // must be normal scan code or extended, nothing else
            UInt8 exIn = scanIn >> 8;
            UInt8 exOut = scanOut >> 8;
            if ((exIn != 0 && exIn != 0xe0) || (exOut != 0 && exOut != 0xe0))
            {
                IOLog("VoodooPS2Keyboard: scan code invalid for PS2 map entry: \"%s\"\n", psz);
                continue;
            }
            // modify PS2 to PS2 map per remap entry
            int index = (scanIn & 0xff) + (exIn == 0xe0 ? KBV_NUM_SCANCODES : 0);
            assert(index < countof(_PS2ToPS2Map));
            _PS2ToPS2Map[index] = (scanOut & 0xff) + (exOut == 0xe0 ? KBV_NUM_SCANCODES : 0);
        }
    }
    
    // now load PS2 -> ADB configuration data
    
    pArray = OSDynamicCast(OSArray, getProperty("Custom ADB Map"));
    if (NULL != pArray)
    {
        for (int i = 0; i < pArray->getCount(); i++)
        {
            OSString* pString = OSDynamicCast(OSString, pArray->getObject(i));
            if (NULL == pString)
                continue;
            const char* psz = pString->getCStringNoCopy();
            // check for comment
            if (';' == *psz)
                continue;
            // otherwise, try to parse it
            UInt16 scanIn, adbOut;
            if (!parseRemap(psz, scanIn, adbOut))
            {
                IOLog("VoodooPS2Keyboard: invalid custom ADB map entry: \"%s\"\n", psz);
                continue;
            }
            // must be normal scan code or extended, nothing else, adbOut is only a byte
            UInt8 exIn = scanIn >> 8;
            if ((exIn != 0 && exIn != 0xe0) || adbOut > 0xFF)
            {
                IOLog("VoodooPS2Keyboard: scan code invalid for ADB map entry: \"%s\"\n", psz);
                continue;
            }
            // modify PS2 to ADB map per remap entry
            int index = (scanIn & 0xff) + (exIn == 0xe0 ? ADB_CONVERTER_EX_START : 0);
            assert(index < countof(_PS2ToADBMap));
            _PS2ToADBMap[index] = adbOut;
        }
    }
    
    // get time before sleep button takes effect
    
    OSNumber* num;
	if ((num = OSDynamicCast(OSNumber, getProperty("SleepPressTime"))))
		maxsleeppresstime = (uint64_t)num->unsigned32BitValue() * (uint64_t)1000000;

    //
    // Reset and enable the keyboard.
    //

    initKeyboard();

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

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

    //
    // Install our power control handler.
    //

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

    return true;
}
// Class start
bool
VoodooPState::start(IOService * provider)
{
	if (!IOService::start(provider)) return false;

	// Printout banner
	InfoLog("%s %s (%s) %s %s [%s]",
			KextProductName,
			KextVersion,
			KextConfig,
			KextBuildDate,
			KextBuildTime,
			KextOSX);
	InfoLog("based on VoodooPower 1.2.3.");
	
	
	
	// Setup workloop and timer
	IOWorkLoop* WorkLoop = getWorkLoop();
	if (!WorkLoop) return false;
	TimerEventSource = 
	IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action,
																	this,
																	&VoodooPState::LoopTimerEvent));
	if (!TimerEventSource) return false;
	
	if (kIOReturnSuccess != WorkLoop->addEventSource(TimerEventSource)) {
		return false;
	}
	
	// Get a SimpleLock
	SimpleLock = IOSimpleLockAlloc();
	if (!SimpleLock) return false;
	
	// Publish the static characteristics
	OSDictionary * dictionary = OSDictionary::withCapacity(13);
	if (!dictionary) return false;
	OSArray * array = OSArray::withCapacity(PStateCount);
	if (!array) return false;
	setDictionaryNumber(keyCpuCoreTech, CpuCoreTech, dictionary);
	setDictionaryNumber(keyFrontSideBus, CpuFSB, dictionary);
	for (int i = 0; i < PStateCount; i++) {
		OSDictionary * pdictionary = OSDictionary::withCapacity(3);
		if (!pdictionary) return false;
		setDictionaryNumber(keyCurrentFrequency, PState[i].frequency, pdictionary);
		setDictionaryNumber(keyCurrentVoltage, PState[i].voltage, pdictionary);
		setDictionaryNumber(keyFid, PState[i].fid, pdictionary);
		setDictionaryNumber(keyDid, PState[i].did, pdictionary);
		setDictionaryNumber(keyVid, PState[i].vid, pdictionary);
		array->setObject(i, pdictionary);
		pdictionary->release();
	}
	setDictionaryArray(keyPStates, array, dictionary);
	setDictionaryString(keyProductName, KextProductName, dictionary);
	setDictionaryString(keyProductVersion, KextVersion, dictionary);
	setDictionaryString(keyBuildConfig, KextConfig, dictionary);
	setDictionaryString(keyBuildDate, KextBuildDate, dictionary);
	setDictionaryString(keyBuildTime, KextBuildTime, dictionary);
	setDictionaryNumber(keyTimerInterval, TimerInterval, dictionary);
	setProperty(keyCharacteristics, dictionary);

	array->release();
	dictionary->release();

	// set initial pstate
	Request = ColdStart ? (PStateCount-1) : 0;	// hot/cold start

	gPEClockFrequencyInfo.cpu_frequency_max_hz = VoodooFrequencyProc(this,&PState[0]) * Mega;
	gPEClockFrequencyInfo.cpu_frequency_min_hz = VoodooFrequencyProc(this,&PState[PStateCount-1]) * Mega;

	LoopTimerEvent();
	
	// Finalize and kick off the loop
	this->registerService(0);
	Ready = true;

	return true;
}
bool IOHIDLibUserClient::start(IOService *provider)
{
    OSDictionary *matching = NULL;
    if (!super::start(provider))
        return false;

    fNub = OSDynamicCast(IOHIDDevice, provider);
    if (!fNub)
        return false;

    fWL = getWorkLoop();
    if (!fWL)
        return false;

    fWL->retain();

    OSNumber *primaryUsage = (OSNumber*)fNub->copyProperty(kIOHIDPrimaryUsageKey);
    OSNumber *primaryUsagePage = (OSNumber*)fNub->copyProperty(kIOHIDPrimaryUsagePageKey);

    if ((OSDynamicCast(OSNumber, primaryUsagePage) && (primaryUsagePage->unsigned32BitValue() == kHIDPage_GenericDesktop)) &&
        (OSDynamicCast(OSNumber, primaryUsage) && ((primaryUsage->unsigned32BitValue() == kHIDUsage_GD_Keyboard) || (primaryUsage->unsigned32BitValue() == kHIDUsage_GD_Keypad))))
    {
        fNubIsKeyboard = true;
    }
    
    OSSafeReleaseNULL(primaryUsage);
    OSSafeReleaseNULL(primaryUsagePage);
            
    IOCommandGate * cmdGate = IOCommandGate::commandGate(this);
    if (!cmdGate)
        goto ABORT_START;
    
    fWL->addEventSource(cmdGate);
    
    fGate = cmdGate;

    fResourceES = IOInterruptEventSource::interruptEventSource
        (this, OSMemberFunctionCast(IOInterruptEventSource::Action, this, &IOHIDLibUserClient::resourceNotificationGated));
        
    if ( !fResourceES )
        goto ABORT_START;

    fWL->addEventSource(fResourceES);

    // Get notified everytime Root properties change
    matching = serviceMatching("IOResources");
    fResourceNotification = addMatchingNotification(
        gIOPublishNotification,
        matching,
        OSMemberFunctionCast(IOServiceMatchingNotificationHandler, this, &IOHIDLibUserClient::resourceNotification),
        this);
    matching->release();
    matching = NULL;

    if ( !fResourceNotification )
        goto ABORT_START;
        
    return true;

ABORT_START:
    if (fResourceES) {
        fWL->removeEventSource(fResourceES);
        fResourceES->release();
        fResourceES = 0;
    }
    if (fGate) {
        fWL->removeEventSource(fGate);
        fGate->release();
        fGate = 0;
    }
    fWL->release();
    fWL = 0;

    return false;
}
bool AppleACPIBatteryDevice::start(IOService *provider)
{
    OSNumber        *debugPollingSetting;
	
    fProvider = OSDynamicCast(AppleACPIBatteryManager, provider);
	
    if (!fProvider || !super::start(provider)) {
        return false;
    }
	
    debugPollingSetting = (OSNumber *)fProvider->getProperty(kBatteryPollingDebugKey);
    if( debugPollingSetting && OSDynamicCast(OSNumber, debugPollingSetting) )
    {
        /* We set our polling interval to the "BatteryPollingPeriodOverride" property's value,
		 in seconds.
		 Polling Period of 0 causes us to poll endlessly in a loop for testing.
         */
        fPollingInterval = debugPollingSetting->unsigned32BitValue();
        fPollingOverridden = true;
    } else {
        fPollingInterval = kDefaultPollInterval;
        fPollingOverridden = false;
    }
	
    fBatteryPresent = false;
    fACConnected = false;
    fACChargeCapable = false;
	
    fWorkLoop = getWorkLoop();
	
    fPollTimer = IOTimerEventSource::timerEventSource( this,
													  OSMemberFunctionCast( IOTimerEventSource::Action,
																		   this, &AppleACPIBatteryDevice::pollingTimeOut) );
	
    fBatteryReadAllTimer = IOTimerEventSource::timerEventSource( this,
																OSMemberFunctionCast( IOTimerEventSource::Action,
																					 this, &AppleACPIBatteryDevice::incompleteReadTimeOut) );
	
    if( !fWorkLoop || !fPollTimer
	   || (kIOReturnSuccess != fWorkLoop->addEventSource(fPollTimer)) )
    {
        return false;
    }
	
    // Publish the intended period in seconds that our "time remaining"
    // estimate is wildly inaccurate after wake from sleep.
    setProperty( kIOPMPSInvalidWakeSecondsKey,		kSecondsUntilValidOnWake, NUM_BITS);
	
    // Publish the necessary time period (in seconds) that a battery
    // calibrating tool must wait to allow the battery to settle after
    // charge and after discharge.
    setProperty( kIOPMPSPostChargeWaitSecondsKey,	kPostChargeWaitSeconds, NUM_BITS);
    setProperty( kIOPMPSPostDishargeWaitSecondsKey, kPostDischargeWaitSeconds, NUM_BITS);
	
#if TEST
    i=0;
#endif
    
    // zero out battery state with argument (do_set == true)
    clearBatteryState(false);
    
    //if system not startup, battery capacity status can't update.
    waitingForSystemStartup();
	
    return true;
}
/******************************************************************************
 * CodecCommander::start - start kernel extension and init PM
 ******************************************************************************/
bool CodecCommander::start(IOService *provider)
{
    IOLog("CodecCommander: Version 2.2.1 starting.\n");

    if (!provider || !super::start(provider))
	{
		DEBUG_LOG("CodecCommander: Error loading kernel extension.\n");
		return false;
	}
    
    // Retrieve HDEF device from IORegistry
	IORegistryEntry *hdaDeviceEntry = IORegistryEntry::fromPath(mConfiguration->getHDADevicePath());
	
    if (hdaDeviceEntry != NULL)
    {
		mIntelHDA = new IntelHDA(hdaDeviceEntry, PIO, mConfiguration->getCodecNumber());
		OSSafeRelease(hdaDeviceEntry);
    }
    else
    {
        DEBUG_LOG("CodecCommander: Device \"%s\" is unreachable, start aborted.\n", mConfiguration->getHDADevicePath());
        return false;
    }
	
	if (mConfiguration->getUpdateNodes())
	{
		IOSleep(mConfiguration->getSendDelay()); // need to wait a bit until codec can actually respond to immediate verbs
		int k = 0; // array index
	
		// Fetch Pin Capabilities from the range of nodes
		DEBUG_LOG("CodecCommander: Getting EAPD supported node list (limited to %d)\n", MAX_EAPD_NODES);
	
		for (int nodeId = mIntelHDA->getStartingNode(); nodeId <= mIntelHDA->getTotalNodes(); nodeId++)
		{
			UInt32 response = mIntelHDA->sendCommand(nodeId, HDA_VERB_GET_PARAM, HDA_PARM_PINCAP);
		
			if (response == -1)
			{
				DEBUG_LOG("CodecCommander: Failed to retrieve pin capabilities for node 0x%02x.\n", nodeId);
				continue;
			}

			// if bit 16 is set in pincap - node supports EAPD
			if (HDA_PINCAP_IS_EAPD_CAPABLE(response))
			{
				eapdCapableNodes[k] = nodeId;
				k++;
				IOLog("CodecCommander: NID=0x%02x supports EAPD, will update state after sleep\n", nodeId);
			}
		}
	
/*
		IOLog("CodecCommander:: Set 0x0A result: 0x%08x\n", mIntelHDA->sendCommand(0x0A, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
		IOLog("CodecCommander:: Set 0x0B result: 0x%08x\n", mIntelHDA->sendCommand(0x0B, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
		IOLog("CodecCommander:: Set 0x0C result: 0x%08x\n", mIntelHDA->sendCommand(0x0C, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
	
		for (int nodeId = mIntelHDA->getStartingNode(); nodeId <= mIntelHDA->getTotalNodes(); nodeId++)
		{
			UInt16 payload = HDA_PARM_AMP_GAIN_GET(0, 1, 1);//AC_AMP_GET_OUTPUT | AC_AMP_GET_LEFT;
			UInt32 response = mIntelHDA->sendCommand(nodeId, HDA_VERB_GET_AMP_GAIN, payload);
		
			if (response == -1)
			{
				DEBUG_LOG("Failed to retrieve amp gain settings for node 0x%02x.\n", nodeId);
				continue;
			}
		
			IOLog("CodecCommander:: [Amp Gain] Node: 0x%04x, Response: 0x%08x\n", nodeId, response);
		}
 */
	}
	
	// Execute any custom commands registered for initialization
	handleStateChange(kStateInit);
	
    // notify about extra feature requests
    if (mConfiguration->getCheckInfinite())
        DEBUG_LOG("CodecCommander: Infinite workloop requested, will start now!\n");
    
    // init power state management & set state as PowerOn
    PMinit();
    registerPowerDriver(this, powerStateArray, kPowerStateCount);
	provider->joinPMtree(this);
    
    // setup workloop and timer
    mWorkLoop = IOWorkLoop::workLoop();
    mTimer = IOTimerEventSource::timerEventSource(this,
                                                  OSMemberFunctionCast(IOTimerEventSource::Action, this,
                                                  &CodecCommander::onTimerAction));
    if (!mWorkLoop || !mTimer)
        stop(provider);;
    
    if (mWorkLoop->addEventSource(mTimer) != kIOReturnSuccess)
        stop(provider);
    
	this->registerService(0);
    return true;
}
Example #15
0
IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void)
{
    return OSMemberFunctionCast(IOInterruptAction,
			this, &IOSharedInterruptController::handleInterrupt);
}
/* 
 * performExternalWordTransaction
 * 
 * Called by AppleSmartBatteryManagerUserClient
 */
IOReturn AppleSmartBatteryManager::performExternalTransaction( 
    void *in,
    void *out,
    IOByteCount inSize,
    IOByteCount *outSize)    
{
    uint16_t                i;
    uint16_t                retryAttempts = 0;
    IOSMBusTransaction      newTransaction;
    IOReturn                transactionSuccess;
    EXSMBUSInputStruct      *inSMBus = (EXSMBUSInputStruct *)in;
    EXSMBUSOutputStruct     *outSMBus = (EXSMBUSOutputStruct *)out;
    
    if (!inSMBus || !outSMBus) 
        return kIOReturnBadArgument;
    
    /* Attempt up to 5 transactions if we get failures
     */
    do {
        bzero(&newTransaction, sizeof(IOSMBusTransaction));    
    
        // Input: bus address
        if (kSMBusAppleDoublerAddr == inSMBus->batterySelector 
            || kSMBusBatteryAddr == inSMBus->batterySelector
            || kSMBusManagerAddr == inSMBus->batterySelector
            || kSMBusChargerAddr == inSMBus->batterySelector) 
        {
            newTransaction.address = inSMBus->batterySelector;
        } else {
            if (0 == inSMBus->batterySelector) 
            {
                newTransaction.address = kSMBusBatteryAddr;
            } else {
                newTransaction.address = kSMBusManagerAddr;
            }
        }
        
        // Input: command
        newTransaction.command = inSMBus->address;
    
        // Input: Read/Write Word/Block
        switch (inSMBus->type) {
            case kEXWriteWord:
                newTransaction.protocol = kIOSMBusProtocolWriteWord;
                newTransaction.sendDataCount = 2;
                break;
            case kEXReadWord:
                newTransaction.protocol = kIOSMBusProtocolReadWord;
                newTransaction.sendDataCount = 0;
                break;
            case kEXWriteBlock:
                newTransaction.protocol = kIOSMBusProtocolWriteBlock;
                // rdar://5433060 workaround for SMC SMBus blockCount bug
                // For block writes, clients always increment inByteCount +1 
                // greater than the actual byte count.
                // We decrement it here for IOSMBusController.
                newTransaction.sendDataCount = inSMBus->inByteCount - 1;
                break;
            case kEXReadBlock:
                newTransaction.protocol = kIOSMBusProtocolReadBlock;
                newTransaction.sendDataCount = 0;
                break;
            case kEXWriteByte:
                newTransaction.protocol = kIOSMBusProtocolWriteByte;
                newTransaction.sendDataCount = 1;
                break;
            case kEXReadByte:
                newTransaction.protocol = kIOSMBusProtocolReadByte;
                newTransaction.sendDataCount = 0;
                break;
            case kEXSendByte:
                newTransaction.protocol = kIOSMBusProtocolSendByte;
                newTransaction.sendDataCount = 0;
                break;
            default:
                return kIOReturnBadArgument;
        }
         
        // Input: copy data into transaction
        //  only need to copy data for write operations
        if ((kIOSMBusProtocolWriteWord == newTransaction.protocol)
             || (kIOSMBusProtocolWriteBlock == newTransaction.protocol))
        {
            for(i = 0; i<MAX_SMBUS_DATA_SIZE; i++) {
                newTransaction.sendData[i] = inSMBus->inBuf[i];    
            }
        }
    
    
        if (inSMBus->flags & kEXFlagRetry) 
        {
            if (retryAttempts >= kMaxRetries) {
                // Don't read off the end of the table...
                retryAttempts = kMaxRetries - 1;
            }
    
            // If this is a retry-on-failure, spin for a few microseconds
            IODelay( retryDelaysTable[retryAttempts] );
        }
    
        fManagerGate->runAction(
                            (IOCommandGate::Action)OSMemberFunctionCast(
                                IOCommandGate::Action, this, 
                                &AppleSmartBatteryManager::performExternalTransactionGated),
                           (void *)&newTransaction, 
                           (void *)&transactionSuccess, 
                           NULL, 
                           NULL);
    
    
        /* Output: status */
        if ((kIOReturnSuccess == transactionSuccess) 
            && (kIOSMBusStatusOK == newTransaction.status))
        {
            outSMBus->status = kIOReturnSuccess;
        } else {
            switch (newTransaction.status) {
                case kIOSMBusStatusUnknownFailure:
                case kIOSMBusStatusDeviceAddressNotAcknowledged:
                case kIOSMBusStatusDeviceError:
                case kIOSMBusStatusDeviceCommandAccessDenied:
                case kIOSMBusStatusUnknownHostError:
                    outSMBus->status = kIOReturnNoDevice;
                    break;
                case kIOSMBusStatusTimeout:
                case kIOSMBusStatusBusy:
                    outSMBus->status = kIOReturnTimeout;                
                    break;
                case kIOSMBusStatusHostUnsupportedProtocol:
                    outSMBus->status = kIOReturnUnsupported;
                    break;
                default:
                    outSMBus->status = kIOReturnInternalError;
                    break;
           }
        }

    /* Retry this transaction if we received a failure
     */
    } while ((inSMBus->flags & kEXFlagRetry) 
          && (outSMBus->status != kIOReturnSuccess) 
          && (++retryAttempts < kMaxRetries));


    /* Output: read word/read block results */    
    if (((kIOSMBusProtocolReadWord == newTransaction.protocol)
         || (kIOSMBusProtocolReadBlock == newTransaction.protocol)
         || (kIOSMBusProtocolReadByte == newTransaction.protocol))
        && (kIOSMBusStatusOK == newTransaction.status))
    {
        outSMBus->outByteCount = newTransaction.receiveDataCount;
        
        for(i = 0; i<outSMBus->outByteCount; i++) {
            outSMBus->outBuf[i] = newTransaction.receiveData[i];    
        }
    }

    return kIOReturnSuccess;
}
/******************************************************************************
 * CodecCommander::start - start kernel extension and init PM
 ******************************************************************************/
bool CodecCommander::start(IOService *provider)
{
    DEBUG_LOG("CodecCommander: cc: commander version 2.1.1 starting\n");

    if(!provider || !super::start( provider ))
	{
		DEBUG_LOG("CodecCommander: cc: error loading kext\n");
		return false;
	}
    
    // notify about extra feature requests
    if (generatePop && checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: stream requested, will *pop* upon wake or fugue-wake\n");
    }
    if (checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: infinite workloop requested, will start now!\n");
    }
    if (generatePop && !checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: stream requested, will *pop* upon wake\n");
    }
    
    // start virtual keyboard device
    _keyboardDevice = new CCHIDKeyboardDevice;
    
    if ( !_keyboardDevice              ||
        !_keyboardDevice->init()       ||
        !_keyboardDevice->attach(this) )
    {
        _keyboardDevice->release();
        DEBUG_LOG("CodecCommander: hi: unable to create keyboard device\n");
    }
    else
    {
        DEBUG_LOG("CodecCommander: hi: keyboard device created\n");
        _keyboardDevice->registerService();
    }
    
    // determine HDEF ACPI device path in IORegistry
    IORegistryEntry *hdaDeviceEntry = IORegistryEntry::fromPath(hdaDevicePath);
    if (hdaDeviceEntry != NULL) {
        IOService *service = OSDynamicCast(IOService, hdaDeviceEntry);
        
        // get address field from IODeviceMemory
        if (service != NULL && service->getDeviceMemoryCount() != 0) {
            ioregEntry = service->getDeviceMemoryWithIndex(0);
            
        }
        hdaDeviceEntry->release();
    }
    else {
        DEBUG_LOG("CodecCommander: %s is unreachable\n",hdaDevicePath);
        return false;
    }
    
    // init power state management & set state as PowerOn
    PMinit();
    registerPowerDriver(this, powerStateArray, kPowerStateCount);
	provider->joinPMtree(this);
    
    // setup workloop and timer
    fWorkLoop = IOWorkLoop::workLoop();
    fTimer = IOTimerEventSource::timerEventSource(this,
                                                          OSMemberFunctionCast(IOTimerEventSource::Action, this,
                                                                               &CodecCommander::onTimerAction));
    if (!fWorkLoop || !fTimer)
        stop(provider);;
    
    if (fWorkLoop->addEventSource(fTimer) != kIOReturnSuccess)
        stop(provider);
    
	this->registerService(0);
    return true;
}
Example #18
0
bool MacRISC2CPU::start(IOService *provider)
{
    kern_return_t        result;
    IORegistryEntry      *cpusRegEntry, *uniNRegEntry, *mpicRegEntry, *devicetreeRegEntry;
    OSIterator           *cpusIterator;
    OSData               *tmpData;
    IOService            *service;
    const OSSymbol       *interruptControllerName;
    OSData               *interruptData;
    OSArray              *tmpArray;
    UInt32               maxCPUs, uniNVersion, physCPU;
    ml_processor_info_t  processor_info;
    
#if enableUserClientInterface    
	DFScontMode = 0;
    fWorkLoop = 0;
    DFS_Status = false;
    GPU_Status = kGPUHigh;
	vStepped = false;
#endif

    // callPlatformFunction symbols
    mpic_getProvider = OSSymbol::withCString("mpic_getProvider");
    mpic_getIPIVector= OSSymbol::withCString("mpic_getIPIVector");
    mpic_setCurrentTaskPriority = OSSymbol::withCString("mpic_setCurrentTaskPriority");
    mpic_setUpForSleep = OSSymbol::withCString("mpic_setUpForSleep");
    mpic_dispatchIPI = OSSymbol::withCString("mpic_dispatchIPI");
    keyLargo_restoreRegisterState = OSSymbol::withCString("keyLargo_restoreRegisterState");
    keyLargo_syncTimeBase = OSSymbol::withCString("keyLargo_syncTimeBase");
    keyLargo_saveRegisterState = OSSymbol::withCString("keyLargo_saveRegisterState");
    keyLargo_turnOffIO = OSSymbol::withCString("keyLargo_turnOffIO");
    keyLargo_writeRegUInt8 = OSSymbol::withCString("keyLargo_writeRegUInt8");
    keyLargo_getHostKeyLargo = OSSymbol::withCString("keyLargo_getHostKeyLargo");
    keyLargo_setPowerSupply = OSSymbol::withCString("setPowerSupply");
    uniN_setPowerState = OSSymbol::withCString(kUniNSetPowerState);
    uniN_setAACKDelay = OSSymbol::withCString(kUniNSetAACKDelay);
	pmu_cpuReset = OSSymbol::withCString("cpuReset");
	ati_prepareDMATransaction = OSSymbol::withCString(kIOFBPrepareDMAValueKey);
    ati_performDMATransaction = OSSymbol::withCString(kIOFBPerformDMAValueKey);
    
    macRISC2PE = OSDynamicCast(MacRISC2PE, getPlatform());
    if (macRISC2PE == 0) return false;
  
    if (!super::start(provider)) return false;

    // Get the Uni-N Version.
    uniNRegEntry = fromPath("/uni-n", gIODTPlane);
    if (uniNRegEntry == 0) return false;
    tmpData = OSDynamicCast(OSData, uniNRegEntry->getProperty("device-rev"));
    if (tmpData == 0) return false;
    uniNVersion = *(long *)tmpData->getBytesNoCopy();
  
    // Find out if this is the boot CPU.
    bootCPU = false;
    tmpData = OSDynamicCast(OSData, provider->getProperty("state"));
    if (tmpData == 0) return false;
    if (!strcmp((char *)tmpData->getBytesNoCopy(), "running")) bootCPU = true;

    // Count the CPUs.
    numCPUs = 0;
    cpusRegEntry = fromPath("/cpus", gIODTPlane);
    if (cpusRegEntry == 0) return false;
    cpusIterator = cpusRegEntry->getChildIterator(gIODTPlane);
    while (cpusIterator->getNextObject()) numCPUs++;
    cpusIterator->release();
  
	// [3830950] - The bootCPU driver inits globals for all instances (like gCPUIC) so if we're not the
	// boot CPU driver we wait here for that driver to finish its initialization
	if ((numCPUs > 1) && !bootCPU)
		// Wait for bootCPU driver to say it's up and running
		(void) waitForService (resourceMatching ("BootCPU"));
		
    // Limit the number of CPUs to one if uniNVersion is 1.0.7 or less.
    if (uniNVersion < kUniNVersion107) numCPUs = 1;
  
    // Limit the number of CPUs by the cpu=# boot arg.
    if (PE_parse_boot_arg("cpus", &maxCPUs))
    {
        if (numCPUs > maxCPUs) numCPUs = maxCPUs;
    }
	
	ignoreSpeedChange = false;
	doSleep = false;
	topLevelPCIBridgeCount = 0;
  
    // Get the "flush-on-lock" property from the first cpu node.
    flushOnLock = false;
    cpusRegEntry = fromPath("/cpus/@0", gIODTPlane);
    if (cpusRegEntry == 0) return false;
    if (cpusRegEntry->getProperty("flush-on-lock") != 0) flushOnLock = true;
  
    // Set flushOnLock when numCPUs is not one.
    if (numCPUs != 1) flushOnLock = true;
  
    // If system is PowerMac3,5 (TowerG4), then set flushOnLock to disable nap
    devicetreeRegEntry = fromPath("/", gIODTPlane);
    tmpData = OSDynamicCast(OSData, devicetreeRegEntry->getProperty("model"));
    if (tmpData == 0) return false;
#if 0
    if(!strcmp((char *)tmpData->getBytesNoCopy(), "PowerMac3,5"))
        flushOnLock = true;
#endif

    // Get the physical CPU number from the "reg" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("reg"));
    if (tmpData == 0) return false;
    physCPU = *(long *)tmpData->getBytesNoCopy();
    setCPUNumber(physCPU);

    // Get the gpio offset for soft reset from the "soft-reset" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("soft-reset"));
    if (tmpData == 0) 
    {
        if (physCPU == 0)
            soft_reset_offset = 0x5B;
        else
            soft_reset_offset = 0x5C;
    }
    else
        soft_reset_offset = *(long *)tmpData->getBytesNoCopy();
   
    // Get the gpio offset for timebase enable from the "timebase-enable" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("timebase-enable"));
    if (tmpData == 0) 
        timebase_enable_offset = 0x73;
    else
        timebase_enable_offset = *(long *)tmpData->getBytesNoCopy();
  
	// See if reset is needed on wake
	resetOnWake = (provider->getProperty ("reset-on-wake") != NULL);
	
	if (resetOnWake) {
		vm_address_t reserveMem;
		

		reserveMem = (vm_address_t)IOMallocAligned (PAGE_SIZE, PAGE_SIZE);	// Get one page (which we keep forever)
		if (reserveMem) {			
			// map it
			reserveMemDesc = IOMemoryDescriptor::withAddress (reserveMem, PAGE_SIZE, kIODirectionNone, NULL);
			if (reserveMemDesc) {
				// get the physical address
				reserveMemPhys = reserveMemDesc->getPhysicalAddress();
			} 
		} 
	}

    // On machines with a 'vmin' property in the CPU Node we need to make sure to tell the kernel to 
    // ml_set_processor_voltage on needed processors.
    needVSetting = (provider->getProperty( "vmin" ) != 0);

    // While techincally the Apollo7PM machines do need AACK delay, it is already set in the bootROM
    // since we boot slow.  We don't want the machine to switch AACKdelay off when we run DFS high so
    // setting this to false will take care of the issue.
        
    needAACKDelay = false;
 
 	if (bootCPU)
    {
        gCPUIC = new IOCPUInterruptController;
        if (gCPUIC == 0) return false;
        if (gCPUIC->initCPUInterruptController(numCPUs) != kIOReturnSuccess)
            return false;
        gCPUIC->attach(this);
        gCPUIC->registerCPUInterruptController();
    }
  
    // Get the l2cr value from the property list.
    tmpData = OSDynamicCast(OSData, provider->getProperty("l2cr"));
    if (tmpData != 0)
    {
        l2crValue = *(long *)tmpData->getBytesNoCopy() & 0x7FFFFFFF;
    }
    else
    {
        l2crValue = mfl2cr() & 0x7FFFFFFF;
    }
  
    // Wait for KeyLargo to show up.
    keyLargo = waitForService(serviceMatching("KeyLargo"));
    if (keyLargo == 0) return false;
  
    keyLargo->callPlatformFunction (keyLargo_getHostKeyLargo, false, &keyLargo, 0, 0, 0);
    if (keyLargo == 0)
    {
        kprintf ("MacRISC2CPU::start - getHostKeyLargo returned nil\n");
        return false;
    }

    // Wait for MPIC to show up.
    mpic = waitForService(serviceMatching("AppleMPICInterruptController"));
    if (mpic == 0) return false;
  
    // Set the Interrupt Properties for this cpu.
    mpic->callPlatformFunction(mpic_getProvider, false, (void *)&mpicRegEntry, 0, 0, 0);
    interruptControllerName = IODTInterruptControllerName(mpicRegEntry);
    mpic->callPlatformFunction(mpic_getIPIVector, false, (void *)&physCPU, (void *)&interruptData, 0, 0);
    if ((interruptControllerName == 0) || (interruptData == 0)) return false;
  
    tmpArray = OSArray::withCapacity(1);
    tmpArray->setObject(interruptControllerName);
    cpuNub->setProperty(gIOInterruptControllersKey, tmpArray);
    tmpArray->release();
  
    tmpArray = OSArray::withCapacity(1);
    tmpArray->setObject(interruptData);
    cpuNub->setProperty(gIOInterruptSpecifiersKey, tmpArray);
    tmpArray->release();
  
    setCPUState(kIOCPUStateUninitalized);
  
	// necessary bootCPU initialization is done, so release other CPU drivers to do their thing
	// other drivers need to be unblocked *before* we call processor_start otherwise we deadlock
	if (bootCPU)
		publishResource ("BootCPU", this);
		
    if (physCPU < numCPUs)
    {
        processor_info.cpu_id           = (cpu_id_t)this;
        processor_info.boot_cpu         = bootCPU;
        processor_info.start_paddr      = 0x0100;
        processor_info.l2cr_value       = l2crValue;
        processor_info.supports_nap     = !flushOnLock;
        processor_info.time_base_enable =
        OSMemberFunctionCast(time_base_enable_t, this, &MacRISC2CPU::enableCPUTimeBase);	// [4091924]
    
        // Register this CPU with mach.
        result = ml_processor_register(&processor_info, &machProcessor,	&ipi_handler);
        if (result == KERN_FAILURE) return false;
    
        processor_start(machProcessor);
    }

    // Before to go to sleep we wish to disable the napping mode so that the PMU
    // will not shutdown the system while going to sleep:
    service = waitForService(serviceMatching("IOPMrootDomain"));
    pmRootDomain = OSDynamicCast(IOPMrootDomain, service);
    if (pmRootDomain != 0)
    {
        kprintf("Register MacRISC2CPU %ld to acknowledge power changes\n", getCPUNumber());
        pmRootDomain->registerInterestedDriver(this);
        
        // Join the Power Management Tree to receive setAggressiveness calls.
        PMinit();
        provider->joinPMtree(this);
    }

    // Finds PMU and UniN so in quiesce we can put the machine to sleep.
    // I can not put these calls there because quiesce runs in interrupt
    // context and waitForService may block.
    pmu = waitForService(serviceMatching("ApplePMU"));
	uniN = waitForService(serviceMatching("AppleUniN"));
    if ((pmu == 0) || (uniN == 0)) return false;
	

    if (macRISC2PE->hasPMon) {
            // Find the platform monitor, if present
            service = waitForService(resourceMatching("IOPlatformMonitor"));
            ioPMon = OSDynamicCast (IOPlatformMonitor, service->getProperty("IOPlatformMonitor"));
            if (!ioPMon) 
                    return false;
            
            ioPMonDict = OSDictionary::withCapacity(2);
            if (!ioPMonDict) {
                    ioPMon = NULL;
            } else {
                    ioPMonDict->setObject (kIOPMonTypeKey, OSSymbol::withCString (kIOPMonTypeCPUCon));
                    ioPMonDict->setObject (kIOPMonCPUIDKey, OSNumber::withNumber ((long long)getCPUNumber(), 32));

                    if (messageClient (kIOPMonMessageRegister, ioPMon, (void *)ioPMonDict) != kIOReturnSuccess) {
                            // IOPMon doesn't need to know about us, so don't bother with it
                            IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformMonitor\n");
                            ioPMonDict->release();
                            ioPMon = NULL;
                    }
            }
    }

    if (macRISC2PE->hasPPlugin) {
		IOService		*ioPPlugin;
		OSDictionary	*ioPPluginDict;
		
		// Find the platform plugin, if present
		service = waitForService(resourceMatching("IOPlatformPlugin"));
		ioPPlugin = OSDynamicCast (IOService, service->getProperty("IOPlatformPlugin"));
		if (!ioPPlugin) 
			return false;
		
		ioPPluginDict = OSDictionary::withCapacity(2);
		if (ioPPluginDict) {
			ioPPluginDict->setObject ("cpu-id", OSNumber::withNumber ((long long)getCPUNumber(), 32));

			// Register with the plugin - same API as for platform monitor
			if (messageClient (kIOPMonMessageRegister, ioPPlugin, (void *)ioPPluginDict) != kIOReturnSuccess) {
				// ioPPlugin doesn't need to know about us, so don't bother with it
				IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformPlugin\n");
			}
			ioPPluginDict->release();	// Not needed any more
		}
    }

#if enableUserClientInterface    
//   
// UserClient stuff...
//  
    fWorkLoop = getWorkLoop();
    if(!fWorkLoop)
    {
            IOLog("MacRISC2CPU::start ERROR: failed to find a fWorkLoop\n");
    }
    if(!initTimers()) 
    {
            IOLog("MacRISC2CPU::start ERROR: failed to init the timers\n");
    }
    
#endif

    registerService();
  
    return true;
}
Example #19
0
void SoftU2FUserClient::frameReceived(IOMemoryDescriptor *report) {
  if (isInactive())
    return;

  _commandGate->runAction(OSMemberFunctionCast(IOCommandGate::Action, this, &SoftU2FUserClient::frameReceivedGated), report);
}
Example #20
0
void MacRISC2CPU::initCPU(bool boot)
{
	IOPCIBridge		*pciDriver;
	UInt32			i;

    if (!boot && bootCPU) {
		// Tell Uni-N to enter normal mode.
		uniN->callPlatformFunction (uniN_setPowerState, false, (void *)kUniNNormal,
			(void *)0, (void *)0, (void *)0);
    
        if (!processorSpeedChange) {

			// Notify our pci children to restore their state
			for (i = 0; i < topLevelPCIBridgeCount; i++)
				if (pciDriver = topLevelPCIBridges[i])
					// Got the driver - send the message
					pciDriver->setDevicePowerState (NULL, 3);


			if (resetOnWake && (!gPHibernateState || !*gPHibernateState)) {
				bool		doAGPRecovery;
				IOReturn	result;
				
				doAGPRecovery = false;
				if (macRISC2PE->atiDriver) {
					// Restore ATI config space
					macRISC2PE->atiDriver->restoreDeviceState();
					if (macRISC2PE->gpuSensor) {
						// Call ATI through the sensor driver to prep for the DMA transaction
						result = macRISC2PE->gpuSensor->callPlatformFunction (ati_prepareDMATransaction, false, (void *)reserveMemDesc, 0, 0, 0);
												
						if (result == kIOReturnSuccess) {
							if (macRISC2PE->atiDriver && macRISC2PE->agpBridgeDriver) {
								// Issue resetAGP to turn on AGP
								macRISC2PE->atiDriver->resetAGP();
								
								// Turn off GART (turned on by resetAGP)
								macRISC2PE->agpBridgeDriver->configWrite32(macRISC2PE->agpBridgeDriver->getBridgeSpace(), 0x94, 0);

								// Call ATI to do the dummy DMA transfer as a test
								result = macRISC2PE->gpuSensor->callPlatformFunction (ati_performDMATransaction, false, (void *)reserveMemDesc, 0, 0, 0);

								// Issue resetAGP to turn off AGP (so it's in state later s/w expects)
								macRISC2PE->atiDriver->resetAGP();

								if (result == kIOReturnDMAError) 
									// DMA failed, to the recovery procedure
									doAGPRecovery = true;
							} 
						} 
					} 
				} 

				if (doAGPRecovery) {
					kprintf("MacRISC2CPU::initCPU - AGP recovery required, issuing cpuReset\n");
					pmu->callPlatformFunction (pmu_cpuReset, false, 0, 0, 0, 0);
					while (1) /* spin waiting for restart*/ ;
				}
			}

			// Continue the wake process
			keyLargo->callPlatformFunction(keyLargo_restoreRegisterState, false, 0, 0, 0, 0);
	
			// Enables the interrupts for this CPU.
			if (macRISC2PE->getMachineType() == kMacRISC2TypePowerMac) {
				haveSleptMPIC = false;
				kprintf("MacRISC2CPU::initCPU %ld -> mpic->setUpForSleep off", getCPUNumber());
				mpic->callPlatformFunction(mpic_setUpForSleep, false, (void *)false, (void *)getCPUNumber(), 0, 0);
			}
		}
    }

    kprintf("MacRISC2CPU::initCPU %ld Here!\n", getCPUNumber());
 
    // Set time base.
    if (bootCPU)
        keyLargo->callPlatformFunction(keyLargo_syncTimeBase, false, 0, 0, 0, 0);
  
    if (boot)
    {
		if (gCPUIC)
			gCPUIC->enableCPUInterrupt(this);
		else
			panic ("MacRISC2CPU: gCPUIC uninitialized for CPU %ld\n", getCPUNumber());
    
        // Register and enable IPIs.
        cpuNub->registerInterrupt(0, this, OSMemberFunctionCast(IOInterruptAction, this, &MacRISC2CPU::ipiHandler), 0);		// [4091924]
        cpuNub->enableInterrupt(0);
    }

	// [5376988] - MPIC is no longer automatically setting priority to 0 so now must do this in all cases, not just non-boot case
	long priority = 0;
	mpic->callPlatformFunction(mpic_setCurrentTaskPriority, false, (void *)&priority, 0, 0, 0);
	
    setCPUState(kIOCPUStateRunning);
}
bool ApplePS2Keyboard::start(IOService * provider)
{
keyi=false;

  //
  // The driver has been instructed to start.   This is called after a
  // successful attach.
  //
  if (!super::start(provider))  return false;

  //
  // Maintain a pointer to and retain the provider object.
  //
  _device = (ApplePS2KeyboardDevice *)provider;
  _device->retain();


  if (kOSBooleanTrue == getProperty("Make capslock into control")) {
    emacsMode = true;
  } else {
    emacsMode = false;
  }
  if (kOSBooleanTrue == getProperty("Swap alt and windows key")) {
    macintoshMode = true;
  } else {
    macintoshMode = false;
  }
  //
  // Install our driver's interrupt handler, for asynchronous data delivery.
  //

  _device->installInterruptAction(this,
            /*(PS2InterruptAction)&ApplePS2Keyboard::interruptOccurred*/
			OSMemberFunctionCast(PS2InterruptAction, this, &ApplePS2Keyboard::interruptOccurred));
  _interruptHandlerInstalled = true;

  //
  // Initialize the keyboard LED state.
  //

  setLEDs(_ledState);

  //
  // Enable the keyboard clock (should already be so), the keyboard IRQ line,
  // and the keyboard Kscan -> scan code translation mode.
  //

  setCommandByte(kCB_EnableKeyboardIRQ | kCB_TranslateMode,
                 kCB_DisableKeyboardClock);

  //
  // Finally, we enable the keyboard itself, so that it may start reporting
  // key events.
  //

  setKeyboardEnable(true);

  //
  // Install our power control handler.
  //

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

  return true;
}
bool ApplePS2CypressTouchPad::start( IOService * provider )
{
    UInt64 enabledProperty;
    UInt64 disabledProperty;

    //
    // 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();

    //
    // Announce hardware properties.
    //

    IOLog("CYPRESS: ApplePS2Trackpad: Cypress Trackpad firmware v%d\n", (UInt8)(_touchPadVersion));

    //
    // Advertise some supported features (tapping, edge scrolling).
    //


//     enabledProperty = 1;
//     disabledProperty = 0; 

//     setProperty("Clicking", enabledProperty, 
//        sizeof(enabledProperty) * 8);
//     setProperty("DragLock", disabledProperty, 
//         sizeof(disabledProperty) * 8);
//     setProperty("Dragging", disabledProperty, 
//        sizeof(disabledProperty) * 8);
//     setProperty("TrackpadScroll", enabledProperty, 
//        sizeof(enabledProperty) * 8);
//     setProperty("TrackpadHorizScroll", enabledProperty, 
//        sizeof(enabledProperty) * 8);

//     setProperty("CypressFourFingerHorizSwipeGesture", ( _fourFingerHorizSwipeGesture ? enabledProperty : disabledProperty),
// 		sizeof(enabledProperty) * 8);
//     setProperty("CypressFourFingerVertSwipeGesture", ( _fourFingerVertSwipeGesture ? enabledProperty : disabledProperty),
//         sizeof(enabledProperty) * 8);
//     setProperty("CypressFiveFingerScreenLock", ( _fiveFingerScreenLock ? enabledProperty : disabledProperty),
//         sizeof(enabledProperty) * 8);
//     setProperty("CypressFiveFingerSleep", (_fiveFingerSleep ? enabledProperty : disabledProperty),
//         sizeof(enabledProperty) * 8);
//     setProperty("CypressThreeFingerDrag", (_threeFingerDrag ? enabledProperty : disabledProperty),
//         sizeof(enabledProperty) * 8);
//        float	i = 200;
//     setProperty("1FingersMaxTapTime", i, sizeof(i) * 8);
//     setProperty("2FingersMaxTapTime", i, sizeof(i) * 8);
//     setProperty("3FingersMaxTapTime", i, sizeof(i) * 8);

    //
    // Must add this property to let our superclass know that it should handle
    // trackpad acceleration settings from user space.  Without this, tracking
    // speed adjustments from the mouse prefs panel have no effect.
    //

    setProperty(kIOHIDPointerAccelerationTypeKey, kIOHIDTrackpadAccelerationType);
    setProperty(kIOHIDScrollAccelerationTypeKey, kIOHIDTrackpadScrollAccelerationKey);

    //
    // Lock the controller during initialization
    //
    
    _device->lock();
    if (_touchPadVersion > 11)
      _tapFrameMax = 11;
    setTouchpadModeByte();
    _device->installInterruptAction(this,
                                    OSMemberFunctionCast(PS2InterruptAction, this, &ApplePS2CypressTouchPad::interruptOccurred),
                                    OSMemberFunctionCast(PS2PacketAction, this, &ApplePS2CypressTouchPad::packetReady));
    _interruptHandlerInstalled = true;
    
    // now safe to allow other threads
    _device->unlock();
    
    //
	// Install our power control handler.
	//

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

    return true;
}