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;
}
Esempio n. 2
0
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
}
Esempio n. 6
0
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);
    }
}
Esempio n. 7
0
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(&currentConfiguration)) != 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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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);
    }
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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);
    }
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
void BrcmPatchRAM::stop(IOService* provider)
{
    uint64_t stop_time, nano_secs;
    clock_get_uptime(&stop_time);
    absolutetime_to_nanoseconds(stop_time - wake_time, &nano_secs);
    uint64_t milli_secs = nano_secs / 1000000;
    AlwaysLog("Time since wake %llu.%llu seconds.\n", milli_secs / 1000, milli_secs % 1000);


    DebugLog("stop\n");

    OSSafeReleaseNULL(mFirmwareStore);

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

    PMstop();

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

    OSSafeReleaseNULL(mDevice);

    super::stop(provider);
}
Esempio n. 28
0
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
0
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;
}