IOReturn BrcmPatchRAM::bulkWrite(const void* data, UInt16 length) { IOReturn result; if (IOMemoryDescriptor* buffer = IOMemoryDescriptor::withAddress((void*)data, length, kIODirectionIn)) { if ((result = buffer->prepare()) == kIOReturnSuccess) { if ((result = mBulkPipe->Write(buffer, 0, 0, buffer->getLength(), (IOUSBCompletion*)NULL)) == kIOReturnSuccess) { //DEBUG_LOG("%s: Wrote %d bytes to bulk pipe.\n", getName(), length); } else AlwaysLog("[%04x:%04x]: Failed to write to bulk pipe (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); } else AlwaysLog("[%04x:%04x]: Failed to prepare bulk write memory buffer (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); if ((result = buffer->complete()) != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: Failed to complete bulk write memory buffer (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); buffer->release(); } else { AlwaysLog("[%04x:%04x]: Unable to allocate bulk write buffer.\n", mVendorId, mProductId); result = kIOReturnNoMemory; } return result; }
bool BrcmPatchRAM::publishResourcePersonality(const char* classname) { // matching dictionary for disabled BrcmFirmwareStore OSDictionary* dict = OSDictionary::withCapacity(3); if (!dict) return false; setStringInDict(dict, kIOProviderClassKey, "disabled_IOResources"); setStringInDict(dict, kIOClassKey, classname); setStringInDict(dict, kIOMatchCategoryKey, classname); // retrieve currently matching IOKit driver personalities OSDictionary* personality = NULL; SInt32 generationCount; if (OSOrderedSet* set = gIOCatalogue->findDrivers(dict, &generationCount)) { if (set->getCount()) DebugLog("%d matching driver personalities for %s.\n", set->getCount(), classname); // should be only one, so we can grab just the first if (OSCollectionIterator* iterator = OSCollectionIterator::withCollection(set)) { personality = OSDynamicCast(OSDictionary, iterator->getNextObject()); iterator->release(); } set->release(); } // if we don't find it, then something is really wrong... if (!personality) { AlwaysLog("unable to find disabled %s personality.\n", classname); dict->release(); return false; } // make copy of personality *before* removing from IOcatalog personality = OSDynamicCast(OSDictionary, personality->copyCollection()); if (!personality) { AlwaysLog("copyCollection failed."); return false; } // unpublish disabled personality gIOCatalogue->removeDrivers(dict, false); // no nub matching on removal dict->release(); // Add new personality into the kernel if (OSArray* array = OSArray::withCapacity(1)) { // change from disabled_IOResources to IOResources setStringInDict(personality, kIOProviderClassKey, "IOResources"); array->setObject(personality); if (gIOCatalogue->addDrivers(array, true)) AlwaysLog("Published new IOKit personality for %s.\n", classname); else AlwaysLog("ERROR in addDrivers for new %s personality.\n", classname); array->release(); } personality->release(); return true; }
bool BatteryTracker::start(IOService* provider) { DebugLog("BatteryTracker::start: entering start\n"); if (!IOService::start(provider)) { AlwaysLog("BatteryTracker: IOService::start failed!\n"); return false; } IOWorkLoop* workLoop = getWorkLoop(); if (!workLoop) { AlwaysLog("BatteryTracker: getWorkLoop failed\n"); return false; } m_pCmdGate = IOCommandGate::commandGate(this); if (!m_pCmdGate) { AlwaysLog("BatteryTracker: IOCommandGate::commmandGate failed\n"); return false; } workLoop->addEventSource(m_pCmdGate); DebugLog("starting BatteryTracker.\n"); m_pBatteryList = OSArray::withCapacity(2); m_pLock = IORecursiveLockAlloc(); registerService(); return true; }
void BrcmPatchRAM::printPersonalities() { // Matching dictionary for the current device OSDictionary* dict = OSDictionary::withCapacity(5); if (!dict) return; setStringInDict(dict, kIOProviderClassKey, kIOUSBDeviceClassName); setNumberInDict(dict, kUSBProductID, mProductId); setNumberInDict(dict, kUSBVendorID, mVendorId); SInt32 generatonCount; if (OSOrderedSet* set = gIOCatalogue->findDrivers(dict, &generatonCount)) { AlwaysLog("[%04x:%04x]: %d matching driver personalities.\n", mVendorId, mProductId, set->getCount()); if (OSCollectionIterator* iterator = OSCollectionIterator::withCollection(set)) { while (OSDictionary* personality = static_cast<OSDictionary*>(iterator->getNextObject())) { OSString* bundleId = OSDynamicCast(OSString, personality->getObject(kBundleIdentifier)); AlwaysLog("[%04x:%04x]: existing IOKit personality \"%s\".\n", mVendorId, mProductId, bundleId->getCStringNoCopy()); } iterator->release(); } set->release(); } dict->release(); }
void BrcmPatchRAM::publishPersonality() { // Matching dictionary for the current device OSDictionary* dict = OSDictionary::withCapacity(5); if (!dict) return; setStringInDict(dict, kIOProviderClassKey, kIOUSBDeviceClassName); setNumberInDict(dict, kUSBProductID, mProductId); setNumberInDict(dict, kUSBVendorID, mVendorId); // Retrieve currently matching IOKit driver personalities OSDictionary* personality = NULL; SInt32 generationCount; if (OSOrderedSet* set = gIOCatalogue->findDrivers(dict, &generationCount)) { if (set->getCount()) DebugLog("[%04x:%04x]: %d matching driver personalities.\n", mVendorId, mProductId, set->getCount()); if (OSCollectionIterator* iterator = OSCollectionIterator::withCollection(set)) { while ((personality = OSDynamicCast(OSDictionary, iterator->getNextObject()))) { if (OSString* bundleId = OSDynamicCast(OSString, personality->getObject(kBundleIdentifier))) if (strncmp(bundleId->getCStringNoCopy(), kAppleBundlePrefix, strlen(kAppleBundlePrefix)) == 0) { AlwaysLog("[%04x:%04x]: Found existing IOKit personality \"%s\".\n", mVendorId, mProductId, bundleId->getCStringNoCopy()); break; } } iterator->release(); } set->release(); } if (!personality && brcmBundleIdentifier) { // OS X does not have a driver personality for this device yet, publish one DebugLog("brcmBundIdentifier: \"%s\"\n", brcmBundleIdentifier->getCStringNoCopy()); DebugLog("brcmIOClass: \"%s\"\n", brcmIOClass->getCStringNoCopy()); dict->setObject(kBundleIdentifier, brcmBundleIdentifier); dict->setObject(kIOClassKey, brcmIOClass); // Add new personality into the kernel if (OSArray* array = OSArray::withCapacity(1)) { array->setObject(dict); if (gIOCatalogue->addDrivers(array, true)) AlwaysLog("[%04x:%04x]: Published new IOKit personality.\n", mVendorId, mProductId); else AlwaysLog("[%04x:%04x]: ERROR in addDrivers for new IOKit personality.\n", mVendorId, mProductId); array->release(); } } dict->release(); #ifdef DEBUG printPersonalities(); #endif }
void BrcmPatchRAM::uploadFirmware() { // signal to timer that firmware already loaded mDevice.setProperty(kFirmwareLoaded, true); // don't bother with devices that have no firmware if (!getProperty(kFirmwareKey)) return; if (!mDevice.open(this)) { AlwaysLog("uploadFirmware could not open the device!\n"); return; } //REVIEW: this block to avoid merge conflicts (remove once merged) ////if (mDevice.open(this)) { // Print out additional device information printDeviceInfo(); // Set device configuration to composite configuration index 0 // Obtain first interface if (setConfiguration(0) && findInterface(&mInterface) && mInterface.open(this)) { DebugLog("set configuration and interface opened\n"); mInterface.findPipe(&mInterruptPipe, kUSBInterrupt, kUSBIn); mInterface.findPipe(&mBulkPipe, kUSBBulk, kUSBOut); if (mInterruptPipe.getValidatedPipe() && mBulkPipe.getValidatedPipe()) { DebugLog("got pipes\n"); if (performUpgrade()) if (mDeviceState == kUpdateComplete) AlwaysLog("[%04x:%04x]: Firmware upgrade completed successfully.\n", mVendorId, mProductId); else AlwaysLog("[%04x:%04x]: Firmware upgrade not needed.\n", mVendorId, mProductId); else AlwaysLog("[%04x:%04x]: Firmware upgrade failed.\n", mVendorId, mProductId); OSSafeReleaseNULL(mReadBuffer); // mReadBuffer is allocated by performUpgrade but not released } mInterface.close(this); } // cleanup if (mInterruptPipe.getValidatedPipe()) { mInterruptPipe.abort(); mInterruptPipe.setPipe(NULL); } if (mBulkPipe.getValidatedPipe()) { mBulkPipe.abort(); mBulkPipe.setPipe(NULL); } mInterface.setInterface(NULL); mDevice.close(this); } }
void BrcmPatchRAM::initBrcmStrings() { if (!brcmBundleIdentifier) { const char* bundle = NULL; const char* ioclass = NULL; const char* providerclass = kIOUSBDeviceClassName; // OS X - Snow Leopard // OS X - Lion if (version_major == 10 || version_major == 11) { bundle = "com.apple.driver.BroadcomUSBBluetoothHCIController"; ioclass = "BroadcomUSBBluetoothHCIController"; } // OS X - Mountain Lion (12.0 until 12.4) else if (version_major == 12 && version_minor <= 4) { bundle = "com.apple.iokit.BroadcomBluetoothHCIControllerUSBTransport"; ioclass = "BroadcomBluetoothHCIControllerUSBTransport"; } // OS X - Mountain Lion (12.5.0) // OS X - Mavericks // OS X - Yosemite else if (version_major == 12 || version_major == 13 || version_major == 14) { bundle = "com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport"; ioclass = "BroadcomBluetoothHostControllerUSBTransport"; } // OS X - El Capitan else if (version_major == 15) { bundle = "com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport"; ioclass = "BroadcomBluetoothHostControllerUSBTransport"; providerclass = kIOUSBHostDeviceClassName; } // OS X - Future releases.... else if (version_major > 15) { AlwaysLog("Unknown new Darwin version %d.%d, using possible compatible personality.\n", version_major, version_minor); bundle = "com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport"; ioclass = "BroadcomBluetoothHostControllerUSBTransport"; providerclass = kIOUSBHostDeviceClassName; } else { AlwaysLog("Unknown Darwin version %d.%d, no compatible personality known.\n", version_major, version_minor); } brcmBundleIdentifier = OSString::withCStringNoCopy(bundle); brcmIOClass = OSString::withCStringNoCopy(ioclass); brcmProviderClass = OSString::withCStringNoCopy(providerclass); } }
bool BrcmPatchRAM::setConfiguration(int configurationIndex) { IOReturn result; const IOUSBConfigurationDescriptor* configurationDescriptor; UInt8 currentConfiguration = 0xFF; // Find the first config/interface UInt8 numconf = 0; if ((numconf = mDevice->GetNumConfigurations()) < (configurationIndex + 1)) { AlwaysLog("[%04x:%04x]: Composite configuration index %d is not available, %d total composite configurations.\n", mVendorId, mProductId, configurationIndex, numconf); return false; } else DebugLog("[%04x:%04x]: Available composite configurations: %d.\n", mVendorId, mProductId, numconf); configurationDescriptor = mDevice->GetFullConfigurationDescriptor(configurationIndex); // Set the configuration to the requested configuration index if (!configurationDescriptor) { AlwaysLog("[%04x:%04x]: No configuration descriptor for configuration index: %d.\n", mVendorId, mProductId, configurationIndex); return false; } if ((result = mDevice->GetConfiguration(¤tConfiguration)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to retrieve active configuration (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } // Device is already configured if (currentConfiguration != 0) { DebugLog("[%04x:%04x]: Device configuration is already set to configuration index %d.\n", mVendorId, mProductId, configurationIndex); return true; } // Set the configuration to the first configuration if ((result = mDevice->SetConfiguration(this, configurationDescriptor->bConfigurationValue, true)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to (re-)configure device (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } DebugLog("[%04x:%04x]: Set device configuration to configuration index %d successfully.\n", mVendorId, mProductId, configurationIndex); return true; }
IOService* BrcmPatchRAM::probe(IOService *provider, SInt32 *probeScore) { extern kmod_info_t kmod_info; uint64_t start_time, end_time, nano_secs; DebugLog("probe\n"); AlwaysLog("Version %s starting on OS X Darwin %d.%d.\n", kmod_info.version, version_major, version_minor); clock_get_uptime(&start_time); mWorkLock = IOLockAlloc(); if (!mWorkLock) return NULL; mCompletionLock = IOLockAlloc(); if (!mCompletionLock) return NULL; mDevice = OSDynamicCast(IOUSBDevice, provider); if (!mDevice) { AlwaysLog("Provider is not a USB device.\n"); return NULL; } mDevice->retain(); initBrcmStrings(); OSString* displayName = OSDynamicCast(OSString, getProperty(kDisplayName)); if (displayName) provider->setProperty(kUSBProductString, displayName); mVendorId = mDevice->GetVendorID(); mProductId = mDevice->GetProductID(); // get firmware here to pre-cache for eventual use on wakeup or now if (BrcmFirmwareStore* firmwareStore = getFirmwareStore()) firmwareStore->getFirmware(OSDynamicCast(OSString, getProperty(kFirmwareKey))); uploadFirmware(); publishPersonality(); clock_get_uptime(&end_time); absolutetime_to_nanoseconds(end_time - start_time, &nano_secs); uint64_t milli_secs = nano_secs / 1000000; AlwaysLog("Processing time %llu.%llu seconds.\n", milli_secs / 1000, milli_secs % 1000); return this; }
bool FakePCIID::init(OSDictionary *propTable) { DebugLog("FakePCIID::init() %p\n", this); // announce version IOLog("FakePCIID: Version %s starting on OS X Darwin %d.%d.\n", kmod_info.version, version_major, version_minor); bool ret = super::init(propTable); if (!ret) { AlwaysLog("super::init returned false\n"); return false; } // place version/build info in ioreg properties RM,Build and RM,Version char buf[128]; snprintf(buf, sizeof(buf), "%s %s", kmod_info.name, kmod_info.version); setProperty("RM,Version", buf); #ifdef DEBUG setProperty("RM,Build", "Debug-" LOGNAME); #else setProperty("RM,Build", "Release-" LOGNAME); #endif // capture vtable pointer for PCIDeviceStub PCIDeviceStub *stub = OSTypeAlloc(PCIDeviceStub); mStubVtable = getVTable(stub); stub->release(); mDeviceVtable = NULL; mProvider = NULL; return true; }
bool FakePCIID::hookProvider(IOService *provider) { if (mDeviceVtable) return true; // already hooked IOPCIDevice *device = OSDynamicCast(IOPCIDevice, provider); if (!device) { AlwaysLog("provider is not a IOPCIDevice: %s\n", provider->getMetaClass()->getClassName()); return false; } // merge FakeProperties into the provider (only properties that do not exist) mergeFakeProperties(provider, "FakeProperties", false); mergeFakeProperties(provider, "FakeProperties-Forced", true); // hook provider IOPCIDevice vtable on attach/start mProvider = device; device->retain(); mDeviceVtable = getVTable(device); setVTable(device, mStubVtable); return true; }
bool USBInterfaceShim::open(IOService *forClient, IOOptionBits options, void *arg) { bool result = m_pInterface->open(forClient, options, arg); if (!result) AlwaysLog("USBInterfaceShim:open failed\n"); return result; }
IOReturn BrcmPatchRAM::setPowerState(unsigned long which, IOService *whom) { DebugLog("setPowerState: which = 0x%lx\n", which); if (which == kMyOffPowerState) { // consider firmware no longer loaded mDevice->removeProperty(kFirmwareLoaded); // in the case the instance is shutting down, don't do anything if (mFirmwareStore) { // unload native bluetooth driver IOReturn result = gIOCatalogue->terminateDriversForModule(brcmBundleIdentifier, false); if (result != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: failure terminating native Broadcom bluetooth (%08x)\n", mVendorId, mProductId, result); else DebugLog("[%04x:%04x]: success terminating native Broadcom bluetooth\n", mVendorId, mProductId); // unpublish native bluetooth personality removePersonality(); } } else if (which == kMyOnPowerState) { clock_get_uptime(&wake_time); // start loading firmware for case probe is never called after wake if (!mDevice->getProperty(kFirmwareLoaded)) mTimer->setTimeoutMS(400); // longest time seen in normal re-probe was ~200ms } return IOPMAckImplied; }
IOUSBInterface* BrcmPatchRAM::findInterface() { // Find the interface for bulk endpoint transfers IOUSBFindInterfaceRequest request; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; if (IOUSBInterface* interface = mDevice->FindNextInterface(NULL, &request)) { interface->retain(); DebugLog("[%04x:%04x]: Interface %d (class %02x, subclass %02x, protocol %02x) located.\n", mVendorId, mProductId, interface->GetInterfaceNumber(), interface->GetInterfaceClass(), interface->GetInterfaceSubClass(), interface->GetInterfaceProtocol()); return interface; } AlwaysLog("[%04x:%04x]: No interface could be located.\n", mVendorId, mProductId); return NULL; }
void BrcmPatchRAM::processWorkQueue(IOInterruptEventSource*, int) { IOLockLock(mWorkLock); // start firmware loading process in a non-workloop thread if (mWorkPending & kWorkLoadFirmware) { DebugLog("_workPending kWorkLoadFirmare\n"); mWorkPending &= ~kWorkLoadFirmware; retain(); kern_return_t result = kernel_thread_start(&BrcmPatchRAM::uploadFirmwareThread, this, &mWorker); if (KERN_SUCCESS == result) DebugLog("Success creating firmware uploader thread\n"); else { AlwaysLog("ERROR creating firmware uploader thread.\n"); release(); } } // firmware loading thread is finished if (mWorkPending & kWorkFinished) { DebugLog("_workPending kWorkFinished\n"); mWorkPending &= ~kWorkFinished; thread_deallocate(mWorker); mWorker = 0; release(); // matching retain when thread created successfully } IOLockUnlock(mWorkLock); }
void BrcmPatchRAM::uploadFirmware() { // get firmware here to pre-cache for eventual use on wakeup or now BrcmFirmwareStore* firmwareStore = getFirmwareStore(); OSArray* instructions = NULL; if (!firmwareStore || !firmwareStore->getFirmware(OSDynamicCast(OSString, getProperty(kFirmwareKey)))) return; if (mDevice->open(this)) { // Print out additional device information printDeviceInfo(); // Set device configuration to composite configuration index 0 // Obtain first interface if (setConfiguration(0) && (mInterface = findInterface()) && mInterface->open(this)) { mInterruptPipe = findPipe(kUSBInterrupt, kUSBIn); mBulkPipe = findPipe(kUSBBulk, kUSBOut); if (mInterruptPipe && mBulkPipe) { if (performUpgrade()) AlwaysLog("[%04x:%04x]: Firmware upgrade completed successfully.\n", mVendorId, mProductId); else AlwaysLog("[%04x:%04x]: Firmware upgrade failed.\n", mVendorId, mProductId); OSSafeReleaseNULL(mReadBuffer); // mReadBuffer is allocated by performUpgrade but not released } mInterface->close(this); } // cleanup if (mInterruptPipe) { mInterruptPipe->Abort(); mInterruptPipe->release(); // retained in findPipe mInterruptPipe = NULL; } if (mBulkPipe) { mBulkPipe->Abort(); mBulkPipe->release(); // retained in findPipe mBulkPipe = NULL; } OSSafeReleaseNULL(mInterface);// retained in findInterface mDevice->close(this); } }
IOReturn BrcmPatchRAM::hciCommand(void * command, UInt16 length) { IOReturn result; if ((result = mInterface.hciCommand(command, length)) != kIOReturnSuccess) AlwaysLog("[%04x:%04x]: device request failed (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return result; }
void BrcmPatchRAM::readCompletion(void* target, void* parameter, IOReturn status, uint32_t bytesTransferred) #endif { BrcmPatchRAM *me = (BrcmPatchRAM*)target; IOLockLock(me->mCompletionLock); IOReturn result = me->mReadBuffer->complete(); if (result != kIOReturnSuccess) DebugLog("[%04x:%04x]: ReadCompletion failed to complete read buffer (\"%s\" 0x%08x).\n", me->mVendorId, me->mProductId, me->stringFromReturn(result), result); switch (status) { case kIOReturnSuccess: #ifndef TARGET_ELCAPITAN me->hciParseResponse(me->mReadBuffer->getBytesNoCopy(), me->mReadBuffer->getLength() - bufferSizeRemaining, NULL, NULL); #else me->hciParseResponse(me->mReadBuffer->getBytesNoCopy(), bytesTransferred, NULL, NULL); #endif break; case kIOReturnAborted: AlwaysLog("[%04x:%04x]: readCompletion - Return aborted (0x%08x)\n", me->mVendorId, me->mProductId, status); me->mDeviceState = kUpdateAborted; break; case kIOReturnNoDevice: AlwaysLog("[%04x:%04x]: readCompletion - No such device (0x%08x)\n", me->mVendorId, me->mProductId, status); me->mDeviceState = kUpdateAborted; break; case kIOUSBTransactionTimeout: AlwaysLog("[%04x:%04x]: readCompletion - Transaction timeout (0x%08x)\n", me->mVendorId, me->mProductId, status); break; case kIOReturnNotResponding: AlwaysLog("[%04x:%04x]: Not responding - Delaying next read.\n", me->mVendorId, me->mProductId); me->mInterruptPipe.clearStall(); break; default: AlwaysLog("[%04x:%04x]: readCompletion - Unknown error (0x%08x)\n", me->mVendorId, me->mProductId, status); me->mDeviceState = kUpdateAborted; break; } IOLockUnlock(me->mCompletionLock); // wake waiting task in performUpgrade (in IOLockSleep)... IOLockWakeup(me->mCompletionLock, me, true); }
bool BrcmPatchRAM::continuousRead() { if (!mReadBuffer) { mReadBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, 0x200); if (!mReadBuffer) { AlwaysLog("[%04x:%04x]: continuousRead - failed to allocate read buffer.\n", mVendorId, mProductId); return false; } #ifndef TARGET_ELCAPITAN mInterruptCompletion.target = this; #else mInterruptCompletion.owner = this; #endif mInterruptCompletion.action = readCompletion; mInterruptCompletion.parameter = NULL; } IOReturn result = mReadBuffer->prepare(); if (result != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: continuousRead - failed to prepare buffer (0x%08x)\n", mVendorId, mProductId, result); return false; } if ((result = mInterruptPipe.read(mReadBuffer, 0, 0, mReadBuffer->getLength(), &mInterruptCompletion)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: continuousRead - Failed to queue read (0x%08x)\n", mVendorId, mProductId, result); if (result == kIOUSBPipeStalled) { mInterruptPipe.clearStall(); result = mInterruptPipe.read(mReadBuffer, 0, 0, mReadBuffer->getLength(), &mInterruptCompletion); if (result != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: continuousRead - Failed, read dead (0x%08x)\n", mVendorId, mProductId, result); return false; } } } return true; }
void BrcmPatchRAM::uploadFirmware() { // signal to timer that firmware already loaded mDevice->setProperty(kFirmwareLoaded, true); if (mDevice->open(this)) { // Print out additional device information printDeviceInfo(); // Set device configuration to composite configuration index 0 // Obtain first interface if (setConfiguration(0) && (mInterface = findInterface()) && mInterface->open(this)) { mInterruptPipe = findPipe(kUSBInterrupt, kUSBIn); mBulkPipe = findPipe(kUSBBulk, kUSBOut); if (mInterruptPipe && mBulkPipe) { if (performUpgrade()) AlwaysLog("[%04x:%04x]: Firmware upgrade completed successfully.\n", mVendorId, mProductId); else AlwaysLog("[%04x:%04x]: Firmware upgrade failed.\n", mVendorId, mProductId); OSSafeReleaseNULL(mReadBuffer); // mReadBuffer is allocated by performUpgrade but not released } mInterface->close(this); } // cleanup if (mInterruptPipe) { mInterruptPipe->Abort(); mInterruptPipe->release(); // retained in findPipe mInterruptPipe = NULL; } if (mBulkPipe) { mBulkPipe->Abort(); mBulkPipe->release(); // retained in findPipe mBulkPipe = NULL; } OSSafeReleaseNULL(mInterface);// retained in findInterface mDevice->close(this); } }
BrcmFirmwareStore* BrcmPatchRAM::getFirmwareStore() { if (!mFirmwareStore) mFirmwareStore = OSDynamicCast(BrcmFirmwareStore, waitForMatchingService(serviceMatching(kBrcmFirmwareStoreService), 2000UL*1000UL*1000UL)); if (!mFirmwareStore) AlwaysLog("[%04x:%04x]: BrcmFirmwareStore does not appear to be available.\n", mVendorId, mProductId); return mFirmwareStore; }
bool NullEthernet::configureInterface(IONetworkInterface *interface) { char modelName[kNameLenght]; ////IONetworkData *data; bool result; DebugLog("configureInterface() ===>\n"); result = super::configureInterface(interface); if (!result) goto done; #if 0 /* Get the generic network statistics structure. */ data = interface->getParameter(kIONetworkStatsKey); if (data) { netStats = (IONetworkStats *)data->getBuffer(); if (!netStats) { AlwaysLog("NullEthernet: Error getting IONetworkStats\n."); result = false; goto done; } } /* Get the Ethernet statistics structure. */ data = interface->getParameter(kIOEthernetStatsKey); if (data) { etherStats = (IOEthernetStats *)data->getBuffer(); if (!etherStats) { AlwaysLog("NullEthernet: Error getting IOEthernetStats\n."); result = false; goto done; } } #endif unitNumber = interface->getUnitNumber(); snprintf(modelName, kNameLenght, "NullEthernet ACPI NULE0000 Gigabit Ethernet"); setProperty("model", modelName); DebugLog("configureInterface() <===\n"); done: return result; }
bool NullEthernet::start(IOService *provider) { DebugLog("start() ===>\n"); if (!super::start(provider)) { AlwaysLog("NullEthernet: IOEthernetController::start failed.\n"); return false; } // retain provider... m_pProvider = OSDynamicCast(IOService, provider); if (!m_pProvider) { AlwaysLog("NullEthernet: No provider.\n"); return false; } m_pProvider->retain(); // initialize MAC address: priority is from DSDT, then provider, last is default if (!initMACfromACPI() && !initMACfromProvider()) { AlwaysLog("Using default MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", m_rgMacAddr[0], m_rgMacAddr[1], m_rgMacAddr[2], m_rgMacAddr[3], m_rgMacAddr[4], m_rgMacAddr[5]); } if (!attachInterface(reinterpret_cast<IONetworkInterface**>(&m_netif))) { AlwaysLog("NullEthernet: attachInterface() failed.\n"); goto error1; } AlwaysLog("NullEthernet: NullEthernet v1.0.0 starting.\n"); done: DebugLog("start() <===\n"); return true; error1: OSSafeReleaseNULL(m_pProvider); return false; }
bool NullEthernet::initMACfromProvider() { bool result = false; OSData* pData = OSDynamicCast(OSData, m_pProvider->getProperty("RM,MAC-address")); if (pData && pData->getLength() == kIOEthernetAddressSize) { bcopy(pData->getBytesNoCopy(), m_rgMacAddr, kIOEthernetAddressSize); AlwaysLog("Using MAC address from provider: %02x:%02x:%02x:%02x:%02x:%02x\n", m_rgMacAddr[0], m_rgMacAddr[1], m_rgMacAddr[2], m_rgMacAddr[3], m_rgMacAddr[4], m_rgMacAddr[5]); result = true; } return result; }
IOReturn BrcmPatchRAM::onTimerEvent() { DebugLog("onTimerEvent\n"); if (!mDevice->getProperty(kFirmwareLoaded)) { AlwaysLog("BLURP!! no firmware loaded and timer expiried (no re-probe)\n"); scheduleWork(kWorkLoadFirmware); } return kIOReturnSuccess; }
bool BrcmPatchRAM::resetDevice() { IOReturn result; if ((result = mDevice->ResetDevice()) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Failed to reset the device (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return false; } else DebugLog("[%04x:%04x]: Device reset.\n", mVendorId, mProductId); return true; }
void BrcmPatchRAM::stop(IOService* provider) { uint64_t stop_time, nano_secs; clock_get_uptime(&stop_time); absolutetime_to_nanoseconds(stop_time - wake_time, &nano_secs); uint64_t milli_secs = nano_secs / 1000000; AlwaysLog("Time since wake %llu.%llu seconds.\n", milli_secs / 1000, milli_secs % 1000); DebugLog("stop\n"); OSSafeReleaseNULL(mFirmwareStore); IOWorkLoop* workLoop = getWorkLoop(); if (workLoop) { if (mTimer) { mTimer->cancelTimeout(); workLoop->removeEventSource(mTimer); mTimer->release(); mTimer = NULL; } if (mWorkSource) { workLoop->removeEventSource(mWorkSource); mWorkSource->release(); mWorkSource = NULL; mWorkPending = 0; } } PMstop(); if (mCompletionLock) { IOLockFree(mCompletionLock); mCompletionLock = NULL; } if (mWorkLock) { IOLockFree(mWorkLock); mWorkLock = NULL; } OSSafeReleaseNULL(mDevice); super::stop(provider); }
bool FakePCIID::start(IOService *provider) { DebugLog("FakePCIID::start() %p\n", this); if (!super::start(provider)) { AlwaysLog("super::start returned false\n"); return false; } if (!hookProvider(provider)) return false; return true; }
int BrcmPatchRAM::getDeviceStatus() { IOReturn result; USBStatus status; if ((result = mDevice->GetDeviceStatus(&status)) != kIOReturnSuccess) { AlwaysLog("[%04x:%04x]: Unable to get device status (\"%s\" 0x%08x).\n", mVendorId, mProductId, stringFromReturn(result), result); return 0; } else DebugLog("[%04x:%04x]: Device status 0x%08x.\n", mVendorId, mProductId, (int)status); return (int)status; }
BrcmFirmwareStore* BrcmPatchRAM::getFirmwareStore() { if (!mFirmwareStore) { // check to see if it already loaded mFirmwareStore = OSDynamicCast(BrcmFirmwareStore, waitForMatchingService(serviceMatching(kBrcmFirmwareStoreService), 0)); if (!mFirmwareStore) { // not loaded, so publish personality... publishResourcePersonality(kBrcmFirmwareStoreService); // and wait... mFirmwareStore = OSDynamicCast(BrcmFirmwareStore, waitForMatchingService(serviceMatching(kBrcmFirmwareStoreService), 2000UL*1000UL*1000UL)); } #ifdef NON_RESIDENT // also need BrcmPatchRAMResidency IOService* residency = OSDynamicCast(BrcmPatchRAMResidency, waitForMatchingService(serviceMatching(kBrcmPatchRAMResidency), 0)); if (!residency) { // not loaded, so publish personality... publishResourcePersonality(kBrcmPatchRAMResidency); // and wait... residency = OSDynamicCast(BrcmPatchRAMResidency, waitForMatchingService(serviceMatching(kBrcmPatchRAMResidency), 2000UL*1000UL*1000UL)); if (residency) residency->release(); else AlwaysLog("[%04x:%04x]: BrcmPatchRAMResidency does not appear to be available.\n", mVendorId, mProductId); } #endif } if (!mFirmwareStore) AlwaysLog("[%04x:%04x]: BrcmFirmwareStore does not appear to be available.\n", mVendorId, mProductId); return mFirmwareStore; }