void IOGUIDPartitionScheme::stop(IOService * provider) { // // Clean up after the media objects we published before terminating. // IOMedia * partition; OSIterator * partitionIterator; // State our assumptions. assert(_partitions); // Detach the media objects we previously attached to the device tree. partitionIterator = OSCollectionIterator::withCollection(_partitions); if ( partitionIterator ) { while ( (partition = (IOMedia *) partitionIterator->getNextObject()) ) { detachMediaObjectFromDeviceTree(partition); } partitionIterator->release(); } super::stop(provider); }
IOReturn AppleLM8x::publishChildren(IOService *nub) { OSIterator *childIterator = NULL; IORegistryEntry *childEntry = NULL; IOService *childNub = NULL; IOReturn status; childIterator = nub->getChildIterator(gIODTPlane); if( childIterator != NULL ) { // Iterate through children and create nubs while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL ) { // Build Table status = buildEntryTable(childEntry); LUNtableElement++; // Publish child as IOService childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService")); childNub->init(childEntry, gIODTPlane); childNub->attach(this); childNub->registerService(); // DLOG("AppleLM8x::publishChildren(0x%x) published child %s\n", kLM8xAddr<<1, childEntry->getName()); } childIterator->release(); } return kIOReturnSuccess; }
void IOPMPagingPlexus::processChildren ( void ) { OSIterator * childIterator; IOPowerConnection * nextChildNub; IORegistryEntry * nextChild; IOService * child; unsigned int i; childIterator = getChildIterator(gIOPowerPlane); if ( childIterator ) { while ( (nextChild = (IORegistryEntry *)(childIterator->getNextObject())) ) { if ( (nextChildNub = OSDynamicCast(IOPowerConnection,nextChild)) ) { child = (IOService *)nextChild->getChildEntry(gIOPowerPlane); if ( child->pm_vars->theControllingDriver ) { for ( i = 1; i < child->pm_vars->theNumberOfPowerStates; i++ ) { child->pm_vars->thePowerStates[i].inputPowerRequirement |= IOPMPagingAvailable; } } if ( child->pm_vars->myCurrentState ) { nextChildNub->setDesiredDomainState(kIOPlexusPowerStateCount-1); } } } childIterator->release(); } }
kern_return_t pmem_iokit_enumerate_pci(pmem_pci_callback_t callback, void *ctx) { kern_return_t error = KERN_FAILURE; OSObject *obj = nullptr; OSDictionary *search = nullptr; OSIterator *iter = nullptr; IOPCIDevice *dev = nullptr; IODeviceMemory *mem = nullptr; IOItemCount mem_count = 0; int cmp; search = IOService::serviceMatching("IOPCIDevice"); iter = IOService::getMatchingServices(search); if (!iter) { pmem_error("Couldn't find any PCI devices."); goto bail; } while ((obj = iter->getNextObject())) { cmp = strncmp("IOPCIDevice", obj->getMetaClass()->getClassName(), strlen("IOPCIDevice")); if (cmp != 0) { // I haven't seen the above return anything other than // PCI devices, but Apple's documentation is sparse (which // is a nice word for what it is) and doesn't actually // say anything about what's guaranteed to be returned. // I'd just as well rather not chance it. pmem_warn("Expected IOPCIDevice but got %s - skipping.", obj->getMetaClass()->getClassName()); continue; } dev = (IOPCIDevice *)obj; mem_count = dev->getDeviceMemoryCount(); pmem_debug("Found PCI device %s", dev->getName()); for (unsigned idx = 0; idx < mem_count; ++idx) { pmem_debug("Memory segment %d found.", idx); mem = dev->getDeviceMemoryWithIndex(idx); pmem_signal_t signal = callback(dev, mem, idx, ctx); if (signal == pmem_Stop) { error = KERN_FAILURE; goto bail; } } } error = KERN_SUCCESS; bail: if (iter) { iter->release(); } if (search) { search->release(); } return error; }
IOReturn IOI2CMaxim1631::publishChildren(IOService *nub) { OSIterator *childIterator = NULL; IORegistryEntry *childEntry = NULL; IOService *childNub = NULL; childIterator = nub->getChildIterator(gIODTPlane); if( childIterator != NULL ) { // Iterate through children and create nubs while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL ) { // Publish child as IOService childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService")); childNub->init(childEntry, gIODTPlane); childNub->attach(this); childNub->registerService(); DLOG("IOI2CMaxim1631::publishChildren(0x%x) published child %s\n", getI2CAddress(), childEntry->getName()); } childIterator->release(); } return kIOReturnSuccess; }
IOACPIPlatformDevice * ACPIBacklightPanel::getChildWithBacklightMethods(IOACPIPlatformDevice * GPUdevice) { DbgLog("%s::%s()\n", this->getName(),__FUNCTION__); OSIterator * iter = NULL; OSObject * entry; iter = GPUdevice->getChildIterator(gIOACPIPlane); if (iter) { while ( true ) { entry = iter->getNextObject(); if (NULL == entry) break; if (entry->metaCast("IOACPIPlatformDevice")) { IOACPIPlatformDevice * device = (IOACPIPlatformDevice *) entry; if (hasBacklightMethods(device)) { IOLog("ACPIBacklight: Found Backlight Device: %s\n", device->getName()); return device; } } else { DbgLog("%s: getChildWithBacklightMethods() Cast Error\n", this->getName()); } } //end while iter->release(); DbgLog("%s: getChildWithBacklightMethods() iterator end\n", this->getName()); } return NULL; }
IOReturn IOI2CLM6x::createChildNubs ( IOService* nub ) { OSIterator* childIterator; IORegistryEntry* childEntry; IOService* childNub; require( ( childIterator = nub->getChildIterator( gIODTPlane ) ) != NULL, IOI2CLM6x_createChildNubs_getChildIteratorNull ); while ( ( childEntry = ( IORegistryEntry * ) childIterator->getNextObject() ) != NULL ) { childNub = OSDynamicCast( IOService, OSMetaClass::allocClassWithName( "IOService" ) ); if ( childNub ) { childNub->init( childEntry, gIODTPlane ); childNub->attach( this ); childNub->registerService(); } } IOI2CLM6x_createChildNubs_getChildIteratorNull: return( kIOReturnSuccess ); }
IOService * ACPIBacklightPanel::getBatteryDevice() { DbgLog("%s::%s()\n", this->getName(),__FUNCTION__); OSDictionary * matching = IOService::serviceMatching("IOPMPowerSource"); OSIterator * iter = NULL; IOService * bat = NULL; if (matching) { DbgLog("%s: getBatteryDevice() serviceMatching OK\n", this->getName()); iter = IOService::getMatchingServices(matching); matching->release(); } if (iter) { DbgLog("%s: getBatteryDevice() iter OK\n", this->getName()); bat = OSDynamicCast(IOService, iter->getNextObject()); if (bat) { DbgLog("%s: getBatteryDevice() bat is of class %s\n", this->getName(), bat->getMetaClass()->getClassName()); } iter->release(); } return bat; }
IOReturn IOI2CDriveBayGPIO::publishChildren(IOService *provider) { IOReturn status = kIOReturnSuccess; OSIterator *iter; IORegistryEntry *next; IOService *nub; if (iter = provider->getChildIterator(gIODTPlane)) { // Iterate through children and create nubs while (next = (IORegistryEntry *)(iter->getNextObject())) { nub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOI2CService")); if (nub) { nub->init(next, gIODTPlane); nub->attach(this); nub->registerService(); // DLOG("IOI2CDriveBayGPIO@%lx::publishChildren published child %s\n", getI2CAddress(), next->getName()); } } iter->release(); } return status; }
void IOPMPagingPlexus::processSiblings ( IOService * aNode ) { OSIterator * parentIterator; IORegistryEntry * nextNub; IORegistryEntry * nextParent; OSIterator * siblingIterator; IORegistryEntry * nextSibling; parentIterator = aNode->getParentIterator(gIOPowerPlane); // iterate parents of this node if ( parentIterator ) { while ( true ) { if ( ! (nextNub = (IORegistryEntry *)(parentIterator->getNextObject())) ) { parentIterator->release(); break; } if ( OSDynamicCast(IOPowerConnection,nextNub) ) { nextParent = nextNub->getParentEntry(gIOPowerPlane); if ( nextParent == getPMRootDomain() ) { continue; // plexus already has root's children } if ( nextParent == this ) { parentIterator->release(); removePowerChild((IOPowerConnection *)nextNub); break; } siblingIterator = nextParent->getChildIterator(gIOPowerPlane); // iterate children of this parent if ( siblingIterator ) { while ( (nextSibling = (IORegistryEntry *)(siblingIterator->getNextObject())) ) { if ( OSDynamicCast(IOPowerConnection,nextSibling) ) { nextSibling = nextSibling->getChildEntry(gIOPowerPlane); if ( nextSibling != aNode ) { // non-ancestor of driver gets addPowerChild((IOService *)nextSibling); // plexus as parent } } } siblingIterator->release(); } processSiblings((IOService *)nextParent); // do the same thing to this parent } } } }
void MacRISC2CPU::haltCPU(void) { OSIterator *childIterator; IORegistryEntry *childEntry, *childDriver; IOPCIBridge *pciDriver; OSData *deviceTypeString; UInt32 i; setCPUState(kIOCPUStateStopped); if (bootCPU) { // Some systems require special handling of Ultra-ATA at sleep. // Call UniN to prepare for that, if necessary uniN->callPlatformFunction ("setupUATAforSleep", false, (void *)0, (void *)0, (void *)0, (void *)0); // Notify our pci children to save their state if (!topLevelPCIBridgeCount) { // First build list of top level bridges - only need to do once as these don't change if ((childIterator = macRISC2PE->getChildIterator (gIOServicePlane)) != NULL) { while ((childEntry = (IORegistryEntry *)(childIterator->getNextObject ())) != NULL) { deviceTypeString = OSDynamicCast( OSData, childEntry->getProperty( "device_type" )); if (deviceTypeString) { if (!strcmp((const char *)deviceTypeString->getBytesNoCopy(), "pci")) { childDriver = childEntry->copyChildEntry(gIOServicePlane); if (childDriver) { pciDriver = OSDynamicCast( IOPCIBridge, childDriver ); if (pciDriver) if (topLevelPCIBridgeCount < kMaxPCIBridges) // Remember this driver topLevelPCIBridges[topLevelPCIBridgeCount++] = pciDriver; else kprintf ("MacRISC2CPU::haltCPU - warning, more than %d PCI bridges - cannot save/restore them all\n", kMaxPCIBridges); childDriver->release(); } } } } childIterator->release(); } } for (i = 0; i < topLevelPCIBridgeCount; i++) if (pciDriver = topLevelPCIBridges[i]) { // Got the driver - send the message pciDriver->setDevicePowerState (NULL, 2); } } kprintf("MacRISC2CPU::haltCPU %ld Here!\n", getCPUNumber()); processor_exit(machProcessor); }
bool AutoThrottler::setup(OSObject* owner) { if (setupDone) return true; workLoop = IOWorkLoop::workLoop(); if (workLoop == 0) return false; perfTimer = IOTimerEventSource::timerEventSource(owner, (IOTimerEventSource::Action) &perfTimerWrapper); if (perfTimer == 0) return false; /* from Superhai (modified by mercurysquad) */ cpu_count = 0; OSDictionary* service; mach_timespec_t serviceTimeout = { 60, 0 }; // in seconds totalTimerEvents = 0; IOService* firstCPU = IOService::waitForService(IOService::serviceMatching("IOCPU"), &serviceTimeout); if (!firstCPU) { warn("IOKit CPUs not found. Auto-throttle may not work.\n"); return false; } else { // we got first cpu, so the others should also be available by now. get them service = IOService::serviceMatching("IOCPU"); } OSIterator* iterator = IOService::getMatchingServices(service); if (!iterator) { warn("IOKit CPU iterator couldn't be created. Auto-throttle may not work.\n"); return false; } IOCPU * cpu; while ((cpu = OSDynamicCast(IOCPU, iterator->getNextObject()))) { /*dbg("Got I/O Kit CPU %d (%u) named %s", cpu_count, (unsigned int)(cpu->getCPUNumber(), cpu->getCPUName()->getCStringNoCopy()); */ mach_cpu[cpu_count] = cpu->getMachProcessor(); if (cpu_count++ > max_cpus) break; } selfHost = host_priv_self(); if (workLoop->addEventSource(perfTimer) != kIOReturnSuccess) return false; currentPState = NumberOfPStates - 1; perfTimer->setTimeoutMS(throttleQuantum * (1 + currentPState)); clock_get_uptime(&lastTime); if (!targetCPULoad) targetCPULoad = defaultTargetLoad; // % x10 sysctl_register_oid(&sysctl__kern_cputhrottle_targetload); sysctl_register_oid(&sysctl__kern_cputhrottle_auto); setupDone = true; return true; }
int num_kids(IOService *provider) { int total = 1; //total++; OSIterator *kids; const char* poo = provider->getName(); IOLog("name: %s \n", poo); if (kids = provider->getChildIterator(gIOServicePlane)) { IOService *nextkid; while (nextkid = (IOService*)kids->getNextObject()) { total += num_kids(nextkid); } kids->release(); } return total; }
static IOReturn _terminateDrivers(OSDictionary * matching) { OSDictionary * dict; OSIterator * iter; IOService * service; IOReturn ret; if ( !matching ) return kIOReturnBadArgument; ret = kIOReturnSuccess; dict = 0; iter = IORegistryIterator::iterateOver(gIOServicePlane, kIORegistryIterateRecursively); if ( !iter ) return kIOReturnNoMemory; UniqueProperties( matching ); // terminate instances. do { iter->reset(); while( (service = (IOService *)iter->getNextObject()) ) { dict = service->getPropertyTable(); if ( !dict ) continue; /* Terminate only for personalities that match the matching dictionary. * This comparison must be done with only the keys in the * "matching" dict to enable general matching. */ if ( !dict->isEqualTo(matching, matching) ) continue; if ( !service->terminate(kIOServiceRequired|kIOServiceSynchronous) ) { ret = kIOReturnUnsupported; break; } } } while( !service && !iter->isValid()); iter->release(); return ret; }
bool AppleACPIBatteryDevice::isStartUp() { OSDictionary * matching = IOService::serviceMatching("AppleBacklightDisplay"); OSIterator * iter = NULL; IOService * service = NULL; if (matching) { iter = IOService::getMatchingServices(matching); matching->release(); } if (iter) { service = OSDynamicCast(IOService, iter->getNextObject()); iter->release(); } return (service != NULL); }
IOReturn IOPMPagingPlexus::setAggressiveness ( unsigned long type, unsigned long ) { OSDictionary * dict; OSIterator * iter; OSObject * next; IOService * candidate = 0; IOService * pagingProvider; if( type != kPMMinutesToSleep) return IOPMNoErr; IOLockLock(ourLock); if ( systemBooting ) { systemBooting = false; IOLockUnlock(ourLock); dict = IOBSDNameMatching(rootdevice); if ( dict ) { iter = getMatchingServices(dict); if ( iter ) { while ( (next = iter->getNextObject()) ) { if ( (candidate = OSDynamicCast(IOService,next)) ) { break; } } iter->release(); } } if ( candidate ) { pagingProvider = findProvider(candidate); if ( pagingProvider ) { processSiblings(pagingProvider); pagingProvider->addPowerChild(this); getPMRootDomain()->removePowerChild(((IOPowerConnection *)getParentEntry(gIOPowerPlane))); processChildren(); } } } else { IOLockUnlock(ourLock); } return IOPMNoErr; }
static IOService * getBatteryDevice() { OSDictionary * matching = IOService::serviceMatching("IOPMPowerSource"); OSIterator * iter = NULL; IOService * bat = NULL; if (matching) { iter = IOService::getMatchingServices(matching); matching->release(); } if (iter) { bat = OSDynamicCast(IOService, iter->getNextObject()); iter->release(); } return bat; }
IORegistryEntry * AppleIntelPIIXATARoot::getDTChannelEntry( int channelID ) { IORegistryEntry * entry = 0; const char * location; OSIterator * iter = _provider->getChildIterator( gIODTPlane ); if (iter == 0) return 0; while (( entry = (IORegistryEntry *) iter->getNextObject() )) { location = entry->getLocation(); if ( location && strtol(location, 0, 10) == channelID ) { entry->retain(); break; } } iter->release(); return entry; // retain held on the entry }
void IODTPlatformExpert::processTopLevel( IORegistryEntry * root ) { OSIterator * kids; IORegistryEntry * next; IORegistryEntry * cpus; IORegistryEntry * options; // infanticide kids = IODTFindMatchingEntries( root, 0, deleteList() ); if( kids) { while( (next = (IORegistryEntry *)kids->getNextObject())) { next->detachAll( gIODTPlane); } kids->release(); } // Publish an IODTNVRAM class on /options. options = root->childFromPath("options", gIODTPlane); if (options) { dtNVRAM = new IODTNVRAM; if (dtNVRAM) { if (!dtNVRAM->init(options, gIODTPlane)) { dtNVRAM->release(); dtNVRAM = 0; } else { dtNVRAM->attach(this); dtNVRAM->registerService(); } } } // Publish the cpus. cpus = root->childFromPath( "cpus", gIODTPlane); if ( cpus) createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0)); // publish top level, minus excludeList createNubs( this, IODTFindMatchingEntries( root, kIODTExclusive, excludeList())); }
static IOService * IOCopyMediaForDev(dev_t device) { OSDictionary * matching; OSNumber * num; OSIterator * iter; IOService * result = 0; matching = IOService::serviceMatching("IOMedia"); if (!matching) return (0); do { num = OSNumber::withNumber(major(device), 32); if (!num) break; matching->setObject(kIOBSDMajorKey, num); num->release(); num = OSNumber::withNumber(minor(device), 32); if (!num) break; matching->setObject(kIOBSDMinorKey, num); num->release(); if (!num) break; iter = IOService::getMatchingServices(matching); if (iter) { result = (IOService *) iter->getNextObject(); result->retain(); iter->release(); } } while (false); matching->release(); return (result); }
bool IOGUIDPartitionScheme::start(IOService * provider) { // // Publish the new media objects which represent our partitions. // IOMedia * partition; OSIterator * partitionIterator; // State our assumptions. assert(_partitions); // Ask our superclass' opinion. if ( super::start(provider) == false ) return false; // Attach and register the new media objects representing our partitions. partitionIterator = OSCollectionIterator::withCollection(_partitions); if ( partitionIterator == 0 ) return false; while ( (partition = (IOMedia *) partitionIterator->getNextObject()) ) { if ( partition->attach(this) ) { attachMediaObjectToDeviceTree(partition); partition->registerService(); } } partitionIterator->release(); return true; }
int PTnVmon::probe_devices() { IOPCIDevice* PTCard=NULL; int i=0; UInt16 vendor_id; IOLog("PTKawainVi: started\n"); OSData* idKey; OSDictionary * iopci = serviceMatching("IOPCIDevice"); OSString* str; #if __LP64__ mach_vm_address_t addr; //mach_vm_size_t size; #else vm_address_t addr; //vm_size_t size; #endif nvclock.num_cards=0; if (iopci) { OSIterator * iterator = getMatchingServices(iopci); if (iterator) { while (PTCard = OSDynamicCast(IOPCIDevice, iterator->getNextObject())) { vendor_id=0; str=OSDynamicCast(OSString, PTCard->getProperty("IOName")); idKey=OSDynamicCast(OSData, PTCard->getProperty("vendor-id")); if (idKey) vendor_id=*(UInt32*)idKey->getBytesNoCopy(); if ((str->isEqualTo("display"))&&(vendor_id==0x10de)){ PTCard->setMemoryEnable(true); nvio = PTCard->mapDeviceMemoryWithIndex(0); addr = (vm_address_t)nvio->getVirtualAddress(); idKey=OSDynamicCast(OSData, PTCard->getProperty("device-id")); if (idKey) nvclock.card[i].device_id=*(UInt32*)idKey->getBytesNoCopy(); IOLog("Vendor ID: %x, Device ID: %x\n", vendor_id, nvclock.card[i].device_id); nvclock.card[i].arch = get_gpu_arch(nvclock.card[i].device_id); IOLog("Architecture: %x\n", nvclock.card[i].arch); nvclock.card[i].number = i; nvclock.card[i].card_name = (char*)get_card_name(nvclock.card[i].device_id, &nvclock.card[i].gpu); IOLog("%s\n", nvclock.card[i].card_name); nvclock.card[i].state = 0; nvclock.card[i].reg_address = addr; map_mem_card( &nvclock.card[i], addr ); i++; } } } } nvclock.num_cards = i; if (!i) { IOLog("PTKawainVi: No nVidia graphics adapters found\n"); } return nvclock.num_cards; }
IOCDMedia * GetCDMediaObjectFromName ( const char * ioBSDNamePtr ) { OSIterator * iteratorPtr = NULL; IORegistryEntry * registryEntryPtr = NULL; IOCDMedia * objectPtr = NULL; OSDictionary * matchingDictPtr = NULL; DebugLog ( ( "GetCDMediaObjectFromName: Entering...\n" ) ); DebugAssert ( ( ioBSDNamePtr != NULL ) ); DebugLog ( ( "GetCDMediaObjectFromName: On enter ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); // Check to see if we need to strip off any leading stuff if ( !strncmp ( ioBSDNamePtr, "/dev/r", 6 ) ) { // Strip off the /dev/r from /dev/rdiskX ioBSDNamePtr = &ioBSDNamePtr[6]; } else if ( !strncmp ( ioBSDNamePtr, "/dev/", 5 ) ) { // Strip off the /dev/ from /dev/diskX ioBSDNamePtr = &ioBSDNamePtr[5]; } if ( strncmp ( ioBSDNamePtr, "disk", 4 ) ) { // Not in correct format, return NULL DebugLog ( ( "GetCDMediaObjectFromName: not in correct format, ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); return NULL; } DebugLog ( ( "GetCDMediaObjectFromName: ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); // Get a dictionary which describes the bsd device matchingDictPtr = IOBSDNameMatching ( ioBSDNamePtr ); // Get an iterator of registry entries iteratorPtr = IOService::getMatchingServices ( matchingDictPtr ); if ( iteratorPtr == NULL ) { DebugLog ( ( "GetCDMediaObjectFromName: iteratorPtr is NULL.\n" ) ); return NULL; } // Release the dictionary matchingDictPtr->release ( ); DebugLog ( ( "Acquired refcount on iterator and media.\n" ) ); // Get the object out of the iterator (NB: we're guaranteed only one object in the iterator // because there is a 1:1 correspondence between BSD Names for devices and IOKit objects registryEntryPtr = ( IORegistryEntry * ) iteratorPtr->getNextObject ( ); if ( registryEntryPtr == NULL ) { DebugLog ( ( "GetCDMediaObjectFromName: registryEntryPtr is NULL.\n" ) ); return NULL; } // Cast it to the correct type objectPtr = OSDynamicCast ( IOCDMedia, registryEntryPtr ); if ( objectPtr == NULL ) { // Cast failed...spew an error DebugLog ( ( "GetCDMediaObjectFromName: objectPtr is NULL, Dynamic Cast failed.\n" ) ); } DebugLog ( ( "GetCDMediaObjectFromName: exiting...\n" ) ); // Bump the refcount on the CDMedia so that when we release the iterator // we still have a refcount on it. if ( objectPtr != NULL ) { objectPtr->retain ( ); } // Release the iterator iteratorPtr->release ( ); return ( objectPtr ); }
// We are the best match, setup driver bool ODINXHostDevice::start(IOService *provider) { LOG(V_DEBUG, "ODINXHostDevice::start called"); this->usbDevice = OSDynamicCast(IOUSBHostDevice, provider); if (!this->usbDevice) { LOG(V_ERROR, "Provider is not an IOUSBHostDevice, this is impossible!"); // Tell the kernel to try the next highest score driver return false; } const StandardUSB::ConfigurationDescriptor *activeConfiguration = nullptr; IOReturn returnCode = NULL; if (!this->usbDevice->isOpen()) { returnCode = this->usbDevice->open(this); if (returnCode != kIOReturnSuccess && returnCode != kIOReturnExclusiveAccess) { /* * Only error if return code is neither kIOReturnSuccess or kIOReturnExclusiveAccess. * If we got kIOReturnExclusiveAccess that means we do (not?) have exclusivity and that open has already been called. */ LOG(V_ERROR, "Error opening the USB device! Code: %04X", returnCode); return false; } LOG(V_DEBUG, "Device is not open and we failed to open it!"); } // DEBUG { LOG(V_NOTE, " Manufacturer: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iManufacturer))); LOG(V_NOTE, " Product: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iProduct))); LOG(V_NOTE, " Serial No: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iSerialNumber))); LOG(V_NOTE, " length: %d\n", this->usbDevice->getDeviceDescriptor()->bLength); LOG(V_NOTE, " device class: %d\n", this->usbDevice->getDeviceDescriptor()->bDeviceClass); LOG(V_NOTE, " S/N: %d\n", this->usbDevice->getDeviceDescriptor()->iSerialNumber); LOG(V_NOTE, " VID:PID: %04X:%04X\n", this->usbDevice->getDeviceDescriptor()->idVendor, this->usbDevice->getDeviceDescriptor()->idProduct); LOG(V_NOTE, " bcdDevice: %04X\n", this->usbDevice->getDeviceDescriptor()->bcdDevice); LOG(V_NOTE, " iMan:iProd:iSer: %d:%d:%d\n", this->usbDevice->getDeviceDescriptor()->iManufacturer, this->usbDevice->getDeviceDescriptor()->iProduct, this->usbDevice->getDeviceDescriptor()->iSerialNumber); LOG(V_NOTE, " nb confs: %d\n", this->usbDevice->getDeviceDescriptor()->bNumConfigurations); } if (this->usbDevice->getDeviceDescriptor()->bNumConfigurations > 0 && returnCode != kIOReturnExclusiveAccess) { for (int configIndex = 0; configIndex < this->usbDevice->getDeviceDescriptor()->bNumConfigurations; configIndex++) { // Set the configuration active, the second param disables IOKit from automaticly trying to find drivers for the new interfaces since we do it ourselves. activeConfiguration = this->usbDevice->getConfigurationDescriptor(configIndex); returnCode = this->usbDevice->setConfiguration(activeConfiguration->bConfigurationValue, false); if (returnCode != kIOReturnSuccess) { LOG(V_ERROR, "Error setting the device to the configuration at index zero!"); } // Find the interfaces OSIterator *deviceInterfaceIterator = this->usbDevice->getChildIterator(gIOServicePlane); if (!deviceInterfaceIterator) { LOG(V_ERROR, "USB Device has no interfaces?!?!"); return false; } OSObject *entry = nullptr; while ((entry = deviceInterfaceIterator->getNextObject()) != nullptr) { IOUSBHostInterface *usbInterface = OSDynamicCast(IOUSBHostInterface, entry); if (!usbInterface) { LOG(V_DEBUG, "Object in interface iterator that isn't a IOUSBHostInterface!"); continue; } uint8_t interfaceClass = usbInterface->getInterfaceDescriptor()->bInterfaceClass; if (interfaceClass != USB_INTERFACE_CLASS_CDC_DATA) { LOG(V_DEBUG, "Interface isn't of the CDC Data class. Interface class: 0x%02X!", interfaceClass); continue; } { LOG(V_NOTE, "config[%d].interface[%d]: num endpoints = %d", configIndex, usbInterface->getInterfaceDescriptor()->bInterfaceNumber, usbInterface->getInterfaceDescriptor()->bNumEndpoints); LOG(V_NOTE, " Class.SubClass.Protocol: %02X.%02X.%02X", usbInterface->getInterfaceDescriptor()->bInterfaceClass, usbInterface->getInterfaceDescriptor()->bInterfaceSubClass, usbInterface->getInterfaceDescriptor()->bInterfaceProtocol); } const StandardUSB::EndpointDescriptor *endpoint = nullptr; while ((endpoint = StandardUSB::getNextEndpointDescriptor(activeConfiguration, usbInterface->getInterfaceDescriptor(), endpoint)) != nullptr) { { LOG(V_NOTE, " endpoint address: %02X\n", endpoint->bEndpointAddress); LOG(V_NOTE, " max packet size: %04X\n", endpoint->wMaxPacketSize); LOG(V_NOTE, " polling interval: %02X\n", endpoint->bInterval); } if (!inPipe || !outPipe) { if (StandardUSB::getEndpointDirection(endpoint)) { if (inPipe) { OSSafeReleaseNULL(inPipe); } this->inPipe = usbInterface->copyPipe(endpoint->bEndpointAddress); LOG(V_DEBUG, "Found an input endpoint: 0x%02X!", endpoint->bEndpointAddress); } else { if (outPipe) { OSSafeReleaseNULL(outPipe); } this->outPipe = usbInterface->copyPipe(endpoint->bEndpointAddress); LOG(V_DEBUG, "Found an output endpoint: 0x%02X!", endpoint->bEndpointAddress); } } } } OSSafeReleaseNULL(deviceInterfaceIterator); } if (!inPipe || !outPipe) { LOG(V_ERROR, "Error opening I/O pipes!"); OSSafeReleaseNULL(inPipe); OSSafeReleaseNULL(outPipe); return false; } } else if (returnCode != kIOReturnExclusiveAccess) { LOG(V_ERROR, "The USB device somehow has no valid configurations?!?!"); return false; } // Retain the device usbDevice->retain(); // Kick off input inPipe->io(inbuf.mdp, PAGE_SIZE, &inbuf.comp); this->handshake(); LOG(V_NOTE, "ODIN Mode device successfully started!"); return true; }
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; }
OSSet * IOPartitionScheme::juxtaposeMediaObjects(OSSet * partitionsOld, OSSet * partitionsNew) { // // Updates a set of existing partitions, represented by partitionsOld, // with possible updates from a rescan of the disk, represented by // partitionsNew. It returns a new set of partitions with the results, // removing partitions from partitionsOld where applicable, adding // partitions from partitionsNew where applicable, and folding in property // changes to partitions from partitionsNew into partitionsOld where // applicable. // OSIterator * iterator = 0; OSIterator * iterator1 = 0; OSIterator * iterator2 = 0; OSSymbol * key; OSSet * keys = 0; IOMedia * partition; IOMedia * partition1; IOMedia * partition2; OSSet * partitions = 0; OSOrderedSet * partitions1 = 0; OSOrderedSet * partitions2 = 0; UInt32 partitionID = 0; OSDictionary * properties; // Allocate a set to hold the set of media objects representing partitions. partitions = OSSet::withCapacity( partitionsNew->getCapacity( ) ); if ( partitions == 0 ) goto juxtaposeErr; // Prepare the reference set of partitions. partitions1 = OSOrderedSet::withCapacity( partitionsOld->getCapacity( ), partitionComparison, 0 ); if ( partitions1 == 0 ) goto juxtaposeErr; iterator1 = OSCollectionIterator::withCollection( partitionsOld ); if ( iterator1 == 0 ) goto juxtaposeErr; while ( ( partition1 = ( IOMedia * ) iterator1->getNextObject( ) ) ) { partitionID = max( partitionID, strtoul( partition1->getLocation( ), NULL, 10 ) ); partitions1->setObject( partition1 ); } iterator1->release( ); iterator1 = 0; // Prepare the comparison set of partitions. partitions2 = OSOrderedSet::withCapacity( partitionsNew->getCapacity( ), partitionComparison, 0 ); if ( partitions2 == 0 ) goto juxtaposeErr; iterator2 = OSCollectionIterator::withCollection( partitionsNew ); if ( iterator2 == 0 ) goto juxtaposeErr; while ( ( partition2 = ( IOMedia * ) iterator2->getNextObject( ) ) ) { partitionID = max( partitionID, strtoul( partition2->getLocation( ), NULL, 10 ) ); partitions2->setObject( partition2 ); } iterator2->release( ); iterator2 = 0; // Juxtapose the partitions. iterator1 = OSCollectionIterator::withCollection( partitions1 ); if ( iterator1 == 0 ) goto juxtaposeErr; iterator2 = OSCollectionIterator::withCollection( partitions2 ); if ( iterator2 == 0 ) goto juxtaposeErr; partition1 = ( IOMedia * ) iterator1->getNextObject( ); partition2 = ( IOMedia * ) iterator2->getNextObject( ); while ( partition1 || partition2 ) { UInt64 base1; UInt64 base2; base1 = partition1 ? partition1->getBase( ) : UINT64_MAX; base2 = partition2 ? partition2->getBase( ) : UINT64_MAX; #if TARGET_OS_EMBEDDED if ( partition1 && partition2 ) { OSString * uuid1; OSString * uuid2; uuid1 = OSDynamicCast( OSString, partition1->getProperty( kIOMediaUUIDKey ) ); uuid2 = OSDynamicCast( OSString, partition2->getProperty( kIOMediaUUIDKey ) ); if ( uuid1 || uuid2 ) { if ( uuid1 == 0 ) { base1 = UINT64_MAX; } else if ( uuid2 == 0 ) { base2 = UINT64_MAX; } else { int compare; compare = strcmp( uuid1->getCStringNoCopy( ), uuid2->getCStringNoCopy( ) ); if ( compare > 0 ) { base1 = UINT64_MAX; } else if ( compare < 0 ) { base2 = UINT64_MAX; } else { base1 = base2; } } } } #endif /* TARGET_OS_EMBEDDED */ if ( base1 > base2 ) { // A partition was added. partition2->setProperty( kIOMediaLiveKey, true ); iterator = OSCollectionIterator::withCollection( partitions1 ); if ( iterator == 0 ) goto juxtaposeErr; while ( ( partition = ( IOMedia * ) iterator->getNextObject( ) ) ) { if ( strcmp( partition->getLocation( ), partition2->getLocation( ) ) == 0 ) { // Set a location value for this partition. char location[ 12 ]; partitionID++; snprintf( location, sizeof( location ), "%d", ( int ) partitionID ); partition2->setLocation( location ); partition2->setProperty( kIOMediaLiveKey, false ); break; } } iterator->release( ); iterator = 0; if ( partition2->attach( this ) ) { attachMediaObjectToDeviceTree( partition2 ); partition2->registerService( kIOServiceAsynchronous ); } partitions->setObject( partition2 ); partition2 = ( IOMedia * ) iterator2->getNextObject( ); } else if ( base1 < base2 ) { // A partition was removed. partition1->setProperty( kIOMediaLiveKey, false ); if ( handleIsOpen( partition1 ) == false ) { partition1->terminate( kIOServiceSynchronous ); detachMediaObjectFromDeviceTree( partition1 ); } else { partition1->removeProperty( kIOMediaPartitionIDKey ); partitions->setObject( partition1 ); } partition1 = ( IOMedia * ) iterator1->getNextObject( ); } else { // A partition was matched. bool edit; bool move; edit = false; move = false; keys = OSSet::withCapacity( 1 ); if ( keys == 0 ) goto juxtaposeErr; properties = partition2->getPropertyTable( ); // Determine which properties were updated. if ( partition1->getBase( ) != partition2->getBase( ) || partition1->getSize( ) != partition2->getSize( ) || partition1->getPreferredBlockSize( ) != partition2->getPreferredBlockSize( ) || partition1->getAttributes( ) != partition2->getAttributes( ) || partition1->isWhole( ) != partition2->isWhole( ) || partition1->isWritable( ) != partition2->isWritable( ) || strcmp( partition1->getContentHint( ), partition2->getContentHint( ) ) ) { edit = true; } if ( strcmp( partition1->getName( ), partition2->getName( ) ) || strcmp( partition1->getLocation( ), partition2->getLocation( ) ) ) { move = true; } iterator = OSCollectionIterator::withCollection( properties ); if ( iterator == 0 ) goto juxtaposeErr; while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) ) { OSObject * value1; OSObject * value2; if ( key->isEqualTo( kIOMediaContentHintKey ) || key->isEqualTo( kIOMediaEjectableKey ) || key->isEqualTo( kIOMediaPreferredBlockSizeKey ) || key->isEqualTo( kIOMediaRemovableKey ) || key->isEqualTo( kIOMediaSizeKey ) || key->isEqualTo( kIOMediaWholeKey ) || key->isEqualTo( kIOMediaWritableKey ) ) { continue; } if ( key->isEqualTo( kIOMediaContentKey ) || key->isEqualTo( kIOMediaLeafKey ) || key->isEqualTo( kIOMediaLiveKey ) || key->isEqualTo( kIOMediaOpenKey ) ) { continue; } value1 = partition1->getProperty( key ); value2 = partition2->getProperty( key ); if ( value1 == 0 || value1->isEqualTo( value2 ) == false ) { keys->setObject( key ); } } iterator->release( ); iterator = 0; // A partition was updated. partition1->setProperty( kIOMediaLiveKey, ( move == false ) ); if ( edit ) { partition1->init( partition2->getBase( ), partition2->getSize( ), partition2->getPreferredBlockSize( ), partition2->getAttributes( ), partition2->isWhole( ), partition2->isWritable( ), partition2->getContentHint( ) ); } if ( keys->getCount( ) ) { iterator = OSCollectionIterator::withCollection( keys ); if ( iterator == 0 ) goto juxtaposeErr; while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) ) { partition1->setProperty( key, partition2->getProperty( key ) ); } iterator->release( ); iterator = 0; } if ( edit || keys->getCount( ) ) { partition1->messageClients( kIOMessageServicePropertyChange ); partition1->registerService( kIOServiceAsynchronous ); } keys->release( ); keys = 0; partitions->setObject( partition1 ); partition1 = ( IOMedia * ) iterator1->getNextObject( ); partition2 = ( IOMedia * ) iterator2->getNextObject( ); } } // Release our resources. iterator1->release( ); iterator2->release( ); partitions1->release( ); partitions2->release( ); return partitions; juxtaposeErr: // Release our resources. if ( iterator ) iterator->release( ); if ( iterator1 ) iterator1->release( ); if ( iterator2 ) iterator2->release( ); if ( keys ) keys->release( ); if ( partitions ) partitions->release( ); if ( partitions1 ) partitions1->release( ); if ( partitions2 ) partitions2->release( ); return 0; }
bool ACPIMonitor::start(IOService * provider) { if (!super::start(provider)) return false; acpiDevice = (IOACPIPlatformDevice *)provider; char key[5]; //Here is Fan in ACPI OSArray* fanNames = OSDynamicCast(OSArray, getProperty("FanNames")); for (int i=0; i<10; i++) { snprintf(key, 5, "FAN%X", i); if (kIOReturnSuccess == acpiDevice->validateObject(key)) { OSString* name = NULL; if (fanNames ) name = OSDynamicCast(OSString, fanNames->getObject(i)); if (!addTachometer(key, name ? name->getCStringNoCopy() : 0)) WarningLog("Can't add tachometer sensor, key %s", key); } else { snprintf(key, 5, "FTN%X", i); if (kIOReturnSuccess == acpiDevice->validateObject(key)) { OSString* name = NULL; if (fanNames ) name = OSDynamicCast(OSString, fanNames->getObject(i)); if (!addTachometer(key, name ? name->getCStringNoCopy() : 0)) WarningLog("Can't add tachometer sensor, key %s", key); } else break; } } //Next step - temperature keys if (kIOReturnSuccess == acpiDevice->validateObject("TCPU")) addSensor("TCPU", KEY_CPU_HEATSINK_TEMPERATURE, TYPE_SP78, 2); if (kIOReturnSuccess == acpiDevice->validateObject("TSYS")) addSensor("TSYS", KEY_NORTHBRIDGE_TEMPERATURE, TYPE_SP78, 2); if (kIOReturnSuccess == acpiDevice->validateObject("TDIM")) addSensor("TDIM", KEY_DIMM_TEMPERATURE, TYPE_SP78, 2); if (kIOReturnSuccess == acpiDevice->validateObject("TAMB")) addSensor("TAMB", KEY_AMBIENT_TEMPERATURE, TYPE_SP78, 2); if (kIOReturnSuccess == acpiDevice->validateObject("TCPP")) addSensor("TCPP", KEY_CPU_PROXIMITY_TEMPERATURE, TYPE_SP78, 2); // We should add also GPU reading stuff for those who has no supported plug in but have the value on EC registers //Voltage if (kIOReturnSuccess == acpiDevice->validateObject("VCPU")) addSensor("VSN0", KEY_CPU_VOLTAGE, TYPE_FP2E, 2); if (kIOReturnSuccess == acpiDevice->validateObject("VMEM")) addSensor("VSN0", KEY_MEMORY_VOLTAGE, TYPE_FP2E, 2); if (kIOReturnSuccess == acpiDevice->validateObject("VSN1")) addSensor("VSN1", "Vp0C", TYPE_FP2E, 2); if (kIOReturnSuccess == acpiDevice->validateObject("VSN2")) addSensor("VSN2", "Vp1C", TYPE_FP2E, 2); if (kIOReturnSuccess == acpiDevice->validateObject("VSN3")) addSensor("VSN3", "Vp2C", TYPE_FP2E, 2); //Amperage if (kIOReturnSuccess == acpiDevice->validateObject("ISN0")) addSensor("ISN0", "ICAC", TYPE_UI16, 2); if (kIOReturnSuccess == acpiDevice->validateObject("ISN1")) addSensor("ISN1", "Ip0C", TYPE_UI16, 2); if (kIOReturnSuccess == acpiDevice->validateObject("ISN2")) addSensor("ISN2", "Ip1C", TYPE_UI16, 2); if (kIOReturnSuccess == acpiDevice->validateObject("ISN3")) addSensor("ISN3", "Ip2C", TYPE_UI16, 2); //Power if (kIOReturnSuccess == acpiDevice->validateObject("PSN0")) addSensor("PSN0", "PC0C", TYPE_UI16, 2); if (kIOReturnSuccess == acpiDevice->validateObject("PSN1")) addSensor("PSN1", "PC1C", TYPE_UI16, 2); // AC Power/Battery if (kIOReturnSuccess == acpiDevice->validateObject("ACDC")) // Power Source Read AC/Battery { addSensor("ACDC", "ACEN", TYPE_UI8, 1); addSensor("ACDC", "ACFP", TYPE_FLAG, 1); addSensor("ACDC", "ACIN", TYPE_FLAG, 1); } // TODO real SMC returns ACID only when AC is plugged, if not is zeroed, so hardcoding it in plist is not OK IMHO // Same goes for ACIC, but no idea how we can get the AC current value.. // Here if ACDC returns 0 we need to set the on battery BATP flag // Battery stuff, need to implement rest of the keys once i figure those if (kIOReturnSuccess == acpiDevice->validateObject("BAK0")) // Battery 0 Current addSensor("BAK0", "B0AC", TYPE_SI16, 2); if (kIOReturnSuccess == acpiDevice->validateObject("BAK1")) // Battery 0 Voltage addSensor("BAK1", "B0AV", TYPE_UI16, 2); //Keys from info.plist OSString *tmpString = 0; OSData *tmpObj = 0; // UInt32 tmpUI32; // char tmpCString[7]; char acpiName[5]; char aKey[5]; OSIterator *iter = 0; const OSSymbol *dictKey = 0; OSDictionary *keysToAdd = 0; keysToAdd = OSDynamicCast(OSDictionary, getProperty("keysToAdd")); if (keysToAdd) { iter = OSCollectionIterator::withCollection(keysToAdd); if (iter) { while ((dictKey = (const OSSymbol *)iter->getNextObject())) { tmpObj = 0; snprintf(acpiName, 5, "%s", dictKey->getCStringNoCopy()); //WarningLog(" Found key %s", acpiName); tmpString = OSDynamicCast(OSString, keysToAdd->getObject(dictKey)); if (tmpString) { snprintf(aKey, 5, "%s", tmpString->getCStringNoCopy()); InfoLog("Custom name=%s key=%s", acpiName, aKey); if (kIOReturnSuccess == acpiDevice->validateObject(acpiName)) { if (aKey[0] == 'F') { if (!addTachometer(aKey, acpiName)) WarningLog("Can't add tachometer sensor, key %s", aKey); } else { addSensor(acpiName, aKey, TYPE_UI16, 2); } } } else { WarningLog(" no value for key %s", acpiName); } } iter->release(); } else { WarningLog(" can't interate keysToAdd"); } } else { WarningLog(" keysToAdd not found"); } registerService(0); return true; }
void FileNVRAM::copyEntryProperties(const char* prefix, IORegistryEntry* entry) { IORegistryEntry* child; OSDictionary* properties; OSCollectionIterator *iter; if (entry) { // Parse all IORegistery Children OSIterator * iterator = entry->getChildIterator(gIODTPlane); if (iterator) { while((child = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != NULL) { const char* name = child->getName(); if (prefix) { size_t size = strlen(prefix) + sizeof(NVRAM_SEPERATOR) + strlen(name); char* newPrefix = (char*)IOMalloc(size); snprintf(newPrefix, size, "%s%s%s", prefix, NVRAM_SEPERATOR, name); copyEntryProperties(newPrefix, child); IOFree(newPrefix, size); } else { copyEntryProperties(name, child); } } iterator->release(); } // Parse entry properties and add them to our self properties = entry->dictionaryWithProperties(); bool result = true; OSObject *object; const OSSymbol *key; iter = OSCollectionIterator::withCollection(properties); if (iter == 0) { return; } while (result) { key = OSDynamicCast(OSSymbol, iter->getNextObject()); if (key == 0) { break; } if (key->isEqualTo("name")) { continue; // Special property in IORegistery, ignore } object = properties->getObject(key); if (object == 0) { continue; } if (prefix) { size_t size = strlen(prefix) + sizeof(NVRAM_SEPERATOR) + strlen(key->getCStringNoCopy()); char* newKey = (char*)IOMalloc(size); snprintf(newKey, size, "%s%s%s", prefix, NVRAM_SEPERATOR, key->getCStringNoCopy()); setProperty(OSSymbol::withCString(newKey), object); IOFree(newKey, size); } else { setProperty(key, object); } } iter->release(); } }