IOUSBControllerV3.cpp [plain text]
#include <libkern/version.h>
#include <libkern/OSDebug.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#include <IOKit/IOHibernatePrivate.h>
#include <IOKit/IOTimerEventSource.h>
#include <IOKit/IOKitKeys.h>
#include <IOKit/usb/IOUSBControllerV3.h>
#include <IOKit/usb/IOUSBRootHubDevice.h>
#include <IOKit/usb/IOUSBHubPolicyMaker.h>
#include <IOKit/usb/IOUSBLog.h>
#include "USBTracepoints.h"
uint32_t * IOUSBControllerV3::_gHibernateState;
#define super IOUSBControllerV2
#define _controllerCanSleep _expansionData->_controllerCanSleep
#define _rootHubPollingRate32 _v3ExpansionData->_rootHubPollingRate32
#define _rootHubTransactionWasAborted _v3ExpansionData->_rootHubTransactionWasAborted
#define _externalUSBDeviceAssertionID _v3ExpansionData->_externalUSBDeviceAssertionID
#define _externalDeviceCount _v3ExpansionData->_externalDeviceCount
#define _inCheckPowerModeSleeping _v3ExpansionData->_inCheckPowerModeSleeping
#define _onThunderbolt _v3ExpansionData->_onThunderbolt
#define _thunderboltModelID _v3ExpansionData->_thunderboltModelID
#define _thunderboltVendorID _v3ExpansionData->_thunderboltVendorID
#define _rootHubNumPortsSS _v3ExpansionData->_rootHubNumPortsSS
#define _rootHubNumPortsHS _v3ExpansionData->_rootHubNumPortsHS
#define _outstandingSSRHTrans _v3ExpansionData->_outstandingSSRHTrans
#define _rootHubPortsSSStartRange _v3ExpansionData->_rootHubPortsSSStartRange
#define _rootHubPortsHSStartRange _v3ExpansionData->_rootHubPortsHSStartRange
#ifndef kIOPMPCISleepResetKey
#define kIOPMPCISleepResetKey "IOPMPCISleepReset"
#endif
#ifndef CONTROLLERV3_USE_KPRINTF
#define CONTROLLERV3_USE_KPRINTF 0
#endif
#if CONTROLLERV3_USE_KPRINTF
#undef USBLog
#undef USBError
void kprintf(const char *format, ...)
__attribute__((format(printf, 1, 2)));
#define USBLog( LEVEL, FORMAT, ARGS... ) if ((LEVEL) <= CONTROLLERV3_USE_KPRINTF) { kprintf( FORMAT "\n", ## ARGS ) ; }
#define USBError( LEVEL, FORMAT, ARGS... ) { kprintf( FORMAT "\n", ## ARGS ) ; }
#endif
OSDefineMetaClass( IOUSBControllerV3, IOUSBControllerV2 )
OSDefineAbstractStructors(IOUSBControllerV3, IOUSBControllerV2)
#pragma mark ееее IOKit methods ееее
bool
IOUSBControllerV3::init(OSDictionary * propTable)
{
if (!super::init(propTable)) return false;
if (!_v3ExpansionData)
{
_v3ExpansionData = (V3ExpansionData *)IOMalloc(sizeof(V3ExpansionData));
if (!_v3ExpansionData)
return false;
bzero(_v3ExpansionData, sizeof(V3ExpansionData));
}
_powerStateChangingTo = kUSBPowerStateStable;
if ( !_gHibernateState )
{
OSData * data = OSDynamicCast(OSData, (IOService::getPMRootDomain())->getProperty(kIOHibernateStateKey));
if (data)
{
_gHibernateState = (uint32_t *) data->getBytesNoCopy();
}
}
return true;
}
bool
IOUSBControllerV3::start( IOService * provider )
{
IOReturn err;
_device = OSDynamicCast(IOPCIDevice, provider);
if (_device == NULL)
{
goto ErrorExit;
}
if (_controllerSpeed == kUSBDeviceSpeedFull)
{
err = CheckForEHCIController(provider);
if (err != kIOReturnSuccess)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::start - CheckForEHCIController returned (%p)", getName(), this, (void*)err);
USBTrace( kUSBTController, kTPControllerV3Start, (uintptr_t)this, err, 0, 1 );
goto ErrorExit;
}
}
if ( !super::start(provider))
{
goto ErrorExit;
}
if (_expansionData && _watchdogUSBTimer && _watchdogTimerActive)
{
_watchdogUSBTimer->cancelTimeout(); _watchdogTimerActive = false;
}
_rootHubTimer = IOTimerEventSource::timerEventSource(this, (IOTimerEventSource::Action) RootHubTimerFired);
if ( _rootHubTimer == NULL )
{
USBLog(1, "IOUSBControllerV3[%p]::UIMInitialize - couldn't allocate timer event source", this);
USBTrace( kUSBTController, kTPControllerV3Start, (uintptr_t)this, kIOReturnNoMemory, 0, 2 );
goto ErrorExit;
}
if ( _workLoop->addEventSource( _rootHubTimer ) != kIOReturnSuccess )
{
USBLog(1, "IOUSBControllerV3[%p]::UIMInitialize - couldn't add timer event source", this);
USBTrace( kUSBTController, kTPControllerV3Start, (uintptr_t)this, kIOReturnError, 0, 3 );
goto ErrorExit;
}
err = InitForPM();
if (err != kIOReturnSuccess)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::start - InitForPM returned (%p)", getName(), this, (void*)err);
USBTrace( kUSBTController, kTPControllerV3Start, (uintptr_t)this, err, 0, 4 );
goto ErrorExit;
}
return true;
ErrorExit:
if (_ehciController)
{
_ehciController->release();
_ehciController = NULL;
}
if (_rootHubTimer)
{
_rootHubTimer->cancelTimeout();
if ( _workLoop )
_workLoop->removeEventSource(_rootHubTimer);
_rootHubTimer->release();
_rootHubTimer = NULL;
}
return false;
}
void
IOUSBControllerV3::stop( IOService * provider )
{
IOPMrootDomain * myRootDomain = getPMRootDomain();
USBLog(5, "IOUSBControllerV3(%s)[%p]::stop isInactive = %d", getName(), this, isInactive());
if (_ehciController)
{
_ehciController->release();
_ehciController = NULL;
}
if (_rootHubTimer)
{
_rootHubTimer->cancelTimeout();
if ( _workLoop )
_workLoop->removeEventSource(_rootHubTimer);
_rootHubTimer->release();
_rootHubTimer = NULL;
}
if (myRootDomain && (kIOPMUndefinedDriverAssertionID != _externalUSBDeviceAssertionID))
{
myRootDomain->releasePMAssertion(_externalUSBDeviceAssertionID);
}
super::stop(provider);
}
bool
IOUSBControllerV3::willTerminate(IOService * provider, IOOptionBits options)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::willTerminate - isInactive(%s)", getName(), this, isInactive() ? "true" : "false");
return super::willTerminate(provider, options);
}
bool
IOUSBControllerV3::didTerminate( IOService * provider, IOOptionBits options, bool * defer )
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::didTerminate - isInactive(%s)", getName(), this, isInactive() ? "true" : "false");
if (_onThunderbolt)
requireMaxBusStall(0);
return super::didTerminate(provider, options, defer);
}
unsigned long
IOUSBControllerV3::maxCapabilityForDomainState ( IOPMPowerFlags domainState )
{
unsigned long ret;
if (isInactive())
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - INACTIVE - assuming full ON", getName(), this);
ret = kUSBPowerStateOn;
}
else
{
ret = super::maxCapabilityForDomainState(domainState);
IOPMPowerFlags domainStateForDoze = kIOPMDoze | (_myPowerStates[kUSBPowerStateOn].inputPowerRequirement & kIOPMClockNormal);
if ( (_myPowerState == kUSBPowerStateSleep) && _gHibernateState && (*_gHibernateState == kIOHibernateStateWakingFromHibernate) && !_wakingFromHibernation && !_v3ExpansionData->_wakingFromStandby)
{
UInt16 configCommand = _device->configRead16(kIOPCIConfigCommand);
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - waking from hibernation - setting flag - kIOPCIConfigCommand(0x%04x)", getName(), this, (int)configCommand);
_device->configWrite16(kIOPCIConfigCommand, configCommand | kIOPCICommandMemorySpace);
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - new kIOPCIConfigCommand(%p)", getName(), this, (void*)_device->configRead16(kIOPCIConfigCommand));
UInt8 pciPMCapOffset = 0;
UInt16 pmControlStatus = 0;
UInt16 pmcsr = 0;
_device->findPCICapability(kIOPCIPowerManagementCapability, &pciPMCapOffset);
if (pciPMCapOffset > kIOPCIConfigMaximumLatency) {
pmControlStatus = pciPMCapOffset + kPCIPMRegBlockPMCSR;
}
if (pmControlStatus)
{
pmcsr = _device->configRead16(pmControlStatus);
if (pmcsr & kPCIPMCSPMEEnable)
{
_v3ExpansionData->_wakingFromStandby = true;
USBLog(1, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - PME_EN bit is set - will wake from S4", getName(), this);
}
}
if (!_v3ExpansionData->_wakingFromStandby)
{
ResetControllerState();
EnableAllEndpoints(true);
_wakingFromHibernation = true;
ret = kUSBPowerStateOff;
}
}
else if (_restarting)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - restarting", getName(), this);
ret = kUSBPowerStateRestart;
}
else if (_poweringDown)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - powering off", getName(), this);
ret = kUSBPowerStateOff;
}
else if (domainState == domainStateForDoze)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - going into the PCI Doze state - we can support full ON..", getName(), this);
ret = kUSBPowerStateOn;
}
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::maxCapabilityForDomainState - domainState[%p], returning[%p]", getName(), this, (void*)domainState, (void*)ret);
return ret;
}
unsigned long
IOUSBControllerV3::initialPowerStateForDomainState ( IOPMPowerFlags domainState )
{
unsigned long ret = super::initialPowerStateForDomainState(domainState);
USBLog(5, "IOUSBControllerV3(%s)[%p]::initialPowerStateForDomainState - domainState[%p], returning[%p]", getName(), this, (void*)domainState, (void*)ret);
return ret;
}
IOReturn
IOUSBControllerV3::powerStateWillChangeTo ( IOPMPowerFlags capabilities, unsigned long stateNumber, IOService* whatDevice)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerStateWillChangeTo - capabilities(%p) - stateNumber (%d) - whatDevice(%p): currrent _myPowerState(%d)", getName(), this, (void*)capabilities, (int)stateNumber, whatDevice, (int)_myPowerState);
_powerStateChangingTo = stateNumber;
return super::powerStateWillChangeTo(capabilities, stateNumber, whatDevice);
}
IOReturn
IOUSBControllerV3::setPowerState( unsigned long powerStateOrdinal, IOService* whatDevice )
{
USBTrace_Start( kUSBTController, kTPControllersetPowerState, (uintptr_t)this, (int)powerStateOrdinal, (uintptr_t)whatDevice, (int)_myPowerState );
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - powerStateOrdinal(%d) - whatDevice(%p) current state(%d)", getName(), this, (int)powerStateOrdinal, whatDevice, (int)_myPowerState);
if ( whatDevice != this )
{
USBLog(1,"IOUSBControllerV3(%s)[%p]::setPowerState - whatDevice != this", getName(), this);
USBTrace( kUSBTController, kTPControllersetPowerState, (uintptr_t)this, 0, 0, 1 );
return kIOPMAckImplied;
}
if ( isInactive() )
{
USBLog(1,"IOUSBControllerV3(%s)[%p]::setPowerState - isInactive - no op", getName(), this);
USBTrace( kUSBTController, kTPControllersetPowerState, (uintptr_t)this, 0, 0, 2 );
_myPowerState = powerStateOrdinal;
return kIOPMAckImplied;
}
if (powerStateOrdinal > kUSBPowerStateOn)
{
USBLog(1,"IOUSBControllerV3(%s)[%p]::setPowerState - bad ordinal(%d)", getName(), this, (int)powerStateOrdinal);
USBTrace( kUSBTController, kTPControllersetPowerState, (uintptr_t)this, 0, 0, 3 );
return kIOPMNoSuchState;
}
if (_myPowerState == powerStateOrdinal)
{
USBLog(5,"IOUSBControllerV3(%s)[%p]::setPowerState - already in correct power state (%d) - no op", getName(), this, (int)_myPowerState);
return kIOPMAckImplied;
}
if ((_myPowerState < kUSBPowerStateLowPower) && (powerStateOrdinal >= kUSBPowerStateLowPower))
{
EnableBusMastering(true);
}
else if ((_myPowerState > kUSBPowerStateSleep) && (powerStateOrdinal <= kUSBPowerStateSleep))
{
if (_expansionData && _watchdogUSBTimer && _watchdogTimerActive)
{
_watchdogUSBTimer->cancelTimeout(); _watchdogTimerActive = false;
}
}
if (_ehciController)
{
if (_wakingFromHibernation)
{
while (_ehciController->_myPowerState <= kUSBPowerStateSleep)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - _wakingFromHibernation - waiting for EHCI controller (%p) to get higher than SLEEP before I proceed - current state (%d)", getName(), this, _ehciController, (int)_myPowerState);
IOSleep(10);
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - done waiting for EHCI controller - current state (%d)", getName(), this, (int)_myPowerState);
}
else
{
if ((_myPowerState < kUSBPowerStateLowPower) && (powerStateOrdinal >= kUSBPowerStateLowPower))
{
while (_ehciController->_myPowerState < kUSBPowerStateLowPower)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - waiting for EHCI controller (%p) to power up before I proceed - current state (%d)", getName(), this, _ehciController, (int)_myPowerState);
IOSleep(10);
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - done waiting for EHCI controller - current state (%d)", getName(), this, (int)_myPowerState);
}
if ((_myPowerState > kUSBPowerStateRestart) && (powerStateOrdinal <= kUSBPowerStateRestart))
{
while (_ehciController->_myPowerState > kUSBPowerStateRestart)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - waiting for EHCI controller (%p) to power down before I proceed - current state (%d)", getName(), this, _ehciController, (int)_myPowerState);
IOSleep(10);
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - done waiting for EHCI controller - current state (%d)", getName(), this, (int)_myPowerState);
}
}
}
HandlePowerChange(powerStateOrdinal);
USBLog(5, "IOUSBControllerV3(%s)[%p]::setPowerState - returning kIOPMAckImplied", getName(), this);
USBTrace_End( kUSBTController, kTPControllersetPowerState, (uintptr_t)this, _myPowerState, 0, 0);
return kIOPMAckImplied;
}
IOReturn
IOUSBControllerV3::powerStateDidChangeTo ( IOPMPowerFlags capabilities, unsigned long stateNumber, IOService* whatDevice)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerStateDidChangeTo - capabilities(%p) - stateNumber (%d) - whatDevice(%p): current state(%d)", getName(), this, (void*)capabilities, (int)stateNumber, whatDevice, (int)_myPowerState);
return super::powerStateDidChangeTo(capabilities, stateNumber, whatDevice);
}
void
IOUSBControllerV3::powerChangeDone ( unsigned long fromState)
{
USBLog((fromState == _myPowerState) ? 7 : 5, "IOUSBControllerV3(%s)[%p]::powerChangeDone - fromState (%d) current state (%d) _wakingFromHibernation(%s) _needToAckPowerDown(%s)", getName(), this, (int)fromState, (int)_myPowerState, _wakingFromHibernation ? "true" : "false", _needToAckPowerDown ? "true" : "false");
_powerStateChangingTo = kUSBPowerStateStable;
if (_v3ExpansionData && (_v3ExpansionData->_wakingFromStandby))
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::powerChangeDone - clearing _wakingFromStandby", getName(), this);
_v3ExpansionData->_wakingFromStandby = false;
}
if (_wakingFromHibernation)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerChangeDone - OFF while _wakingFromHibernation - turning ON", getName(), this);
_wakingFromHibernation = false;
_poweringDown = false;
_restarting = false;
changePowerStateToPriv(kUSBPowerStateOn); EnsureUsability(); changePowerStateToPriv(kUSBPowerStateLowPower); }
else if (_needToAckPowerDown)
{
if (_myPowerState == kUSBPowerStateRestart)
{
_needToAckPowerDown = false;
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerChangeDone - acknowledging systemWillShutdown(kIOMessageSystemWillRestart)", getName(), this);
IOService::systemWillShutdown(kIOMessageSystemWillRestart);
}
else if (_myPowerState == kUSBPowerStateOff)
{
_needToAckPowerDown = false;
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerChangeDone - acknowledging systemWillShutdown(kIOMessageSystemWillPowerOff)", getName(), this);
IOService::systemWillShutdown(kIOMessageSystemWillPowerOff);
}
else
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::powerChangeDone - NOT acknowledging systemWillShutdown yet", getName(), this);
}
}
super::powerChangeDone(fromState);
}
void
IOUSBControllerV3::systemWillShutdown( IOOptionBits specifier )
{
bool ackNow = true;
USBLog(5, "IOUSBControllerV3(%s)[%p]::systemWillShutdown - specifier(%p)", getName(), this, (void*)specifier);
switch (specifier)
{
case kIOMessageSystemWillRestart:
ackNow = false;
_needToAckPowerDown = true;
_restarting = true;
USBLog(5, "IOUSBControllerV3(%s)[%p]::systemWillShutdown - changing power state to restart", getName(), this);
changePowerStateToPriv(kUSBPowerStateRestart);
powerOverrideOnPriv();
break;
case kIOMessageSystemWillPowerOff:
ackNow = false;
_needToAckPowerDown = true;
_poweringDown = true;
USBLog(5, "IOUSBControllerV3(%s)[%p]::systemWillShutdown - changing power state to off", getName(), this);
changePowerStateToPriv(kUSBPowerStateOff);
powerOverrideOnPriv();
break;
default:
break;
}
if (ackNow)
{
USBLog(5, "AppleUSBUHCI[%p]::systemWillShutdown - acknowledging", this);
IOService::systemWillShutdown(specifier);
}
}
void
IOUSBControllerV3::free()
{
if (_v3ExpansionData)
{
IOFree(_v3ExpansionData, sizeof(V3ExpansionData));
_v3ExpansionData = NULL;
}
super::free();
}
#pragma mark ееее class methods ееее
IOReturn
IOUSBControllerV3::CheckForEHCIController(IOService *provider)
{
OSIterator *siblings = NULL;
OSIterator *ehciList = NULL;
IOService *service;
IORegistryEntry *entry;
bool ehciPresent = false;
int myDeviceNum = 0;
int ehciDeviceNum = 0;
IOUSBControllerV3 * testEHCI = NULL;
int checkListCount = 0;
USBLog(6, "+%s[%p]::CheckForEHCIController", getName(), this);
if ( _device )
{
myDeviceNum = _device->getDeviceNumber();
}
if (provider)
{
siblings = provider->getParentEntry(gIOServicePlane)->getChildIterator(gIOServicePlane);
}
else
{
USBLog(2, "%s[%p]::CheckForEHCIController - NULL provider", getName(), this);
}
if ( siblings )
{
while( (entry = OSDynamicCast(IORegistryEntry, siblings->getNextObject())))
{
UInt32 classCode;
OSData *obj = OSDynamicCast(OSData, entry->getProperty("class-code"));
if (obj)
{
classCode = *(UInt32 *)obj->getBytesNoCopy();
if (classCode == 0x0c0320)
{
ehciPresent = true;
break;
}
}
}
siblings->release();
}
else
{
USBLog(2, "%s[%p]::CheckForEHCIController - NULL siblings", getName(), this);
}
if (ehciPresent)
{
OSDictionary * matchingDictionary = serviceMatching("AppleUSBEHCI");
USBLog(7, "%s[%p]::CheckForEHCIController calling waitForMatchingService for AppleUSBEHCI", getName(), this);
if (matchingDictionary)
{
service = waitForMatchingService( matchingDictionary, (uint64_t)(5 * NSEC_PER_SEC));
testEHCI = (IOUSBControllerV3*)service;
}
while (testEHCI)
{
IOPCIDevice * testPCI = (IOPCIDevice*)testEHCI->getParentEntry(gIOServicePlane);
ehciDeviceNum = testPCI->getDeviceNumber();
if (myDeviceNum == ehciDeviceNum)
{
USBLog(5, "%s[%p]::CheckForEHCIController - ehciDeviceNum and myDeviceNum match (%d)", getName(), this, myDeviceNum);
_ehciController = testEHCI;
_ehciController->retain();
testEHCI->release(); USBLog(7, "%s[%p]::CheckForEHCIController got EHCI service %p", getName(), this, service);
setProperty("Companion", "yes");
break;
}
else
{
USBLog(5, "%s[%p]::CheckForEHCIController - ehciDeviceNum(%d) and myDeviceNum(%d) do NOT match", getName(), this, ehciDeviceNum, myDeviceNum);
testEHCI->release();
if (ehciList)
{
testEHCI = (IOUSBControllerV3*)(ehciList->getNextObject());
if (testEHCI)
{
USBLog(3, "%s[%p]::CheckForEHCIController - found AppleUSBEHCI after %d ms", getName(), this, checkListCount * 10);
testEHCI->retain();
}
}
else
{
testEHCI = NULL;
}
if (!testEHCI && (checkListCount++ < 500))
{
if (ehciList)
ehciList->release();
IOSleep(10);
USBLog(5, "%s[%p]::CheckForEHCIController - getting an AppleUSBEHCI list", getName(), this);
ehciList = getMatchingServices(matchingDictionary);
if (ehciList)
{
testEHCI = (IOUSBControllerV3*)(ehciList->getNextObject());
if (testEHCI)
{
USBLog(5, "%s[%p]::CheckForEHCIController - got AppleUSBEHCI[%p] from the list", getName(), this, testEHCI);
testEHCI->retain(); }
}
}
}
}
}
if ( !ehciPresent || checkListCount == 500 )
{
USBError(1, "We could not find a corresponding USB EHCI controller for our OHCI controller at PCI device number%d", myDeviceNum);
}
if (ehciList)
ehciList->release();
USBLog(6, "-%s[%p]::CheckForEHCIController", getName(), this);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::AllocatePowerStateArray(void)
{
unsigned long i;
_numPowerStates = kUSBNumberBusPowerStates;
_myPowerStates = (IOPMPowerState*)IOMalloc(kUSBNumberBusPowerStates * sizeof(IOPMPowerState));
if (!_myPowerStates)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::AllocatePowerStateArray - no memory", getName(), this);
USBTrace( kUSBTController, kTPAllocatePowerStateArray, (uintptr_t)this, kIOReturnNoMemory, 0, 0 );
return kIOReturnNoMemory;
}
bzero(_myPowerStates, kUSBNumberBusPowerStates * sizeof(IOPMPowerState));
for (i=0; i < _numPowerStates; i++)
{
_myPowerStates[i].version = kIOPMPowerStateVersion1;
}
_myPowerStates[kUSBPowerStateRestart].capabilityFlags = kIOPMRestartCapability;
_myPowerStates[kUSBPowerStateRestart].outputPowerCharacter = kIOPMRestart;
_myPowerStates[kUSBPowerStateSleep].capabilityFlags = kIOPMSleepCapability;
_myPowerStates[kUSBPowerStateSleep].outputPowerCharacter = kIOPMSleep;
_myPowerStates[kUSBPowerStateSleep].inputPowerRequirement = _controllerCanSleep ? 0 : kIOPMSleep;
_myPowerStates[kUSBPowerStateLowPower].capabilityFlags = kIOPMLowPower;
_myPowerStates[kUSBPowerStateLowPower].outputPowerCharacter = kIOPMLowPower;
_myPowerStates[kUSBPowerStateLowPower].inputPowerRequirement = IOPMPowerOn;
_myPowerStates[kUSBPowerStateOn].capabilityFlags = IOPMDeviceUsable;
_myPowerStates[kUSBPowerStateOn].outputPowerCharacter = IOPMPowerOn;
_myPowerStates[kUSBPowerStateOn].inputPowerRequirement = IOPMPowerOn;
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::InitForPM(void)
{
IOReturn err;
IOPMrootDomain * myRootDomain = getPMRootDomain();
err = AllocatePowerStateArray();
if (err)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::InitForPM - AllocatePowerStateArray returned (%p)", getName(), this, (void*)err);
USBTrace( kUSBTController, kTPInitForPM, (uintptr_t)this, err, 0, 0 );
return kIOReturnNoMemory;
}
if (myRootDomain)
{
_externalUSBDeviceAssertionID = myRootDomain->createPMAssertion(kIOPMDriverAssertionUSBExternalDeviceBit, kIOPMDriverAssertionLevelOff, this, _device->getName());
if (kIOPMUndefinedDriverAssertionID == _externalUSBDeviceAssertionID)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::InitForPM - createPMAssertion failed", getName(), this);
}
}
makeUsable();
USBLog(3, "IOUSBControllerV3(%s)[%p]::InitForPM - calling registerPowerDriver", getName(), this);
registerPowerDriver(this, _myPowerStates, _numPowerStates);
changePowerStateTo(kUSBPowerStateLowPower);
changePowerStateToPriv(kUSBPowerStateLowPower);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::CheckPowerModeBeforeGatedCall(char *fromStr)
{
#pragma unused (fromStr)
IOReturn kr = kIOReturnSuccess;
SInt32 retries = 100;
if (!_workLoop) return kIOReturnNotPermitted;
if (_myPowerState != kUSBPowerStateOn)
{
if ((_powerStateChangingTo != kUSBPowerStateStable) && (_powerStateChangingTo != kUSBPowerStateOn))
{
USBLog(2, "IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall from (%s) - we are already in the process of changing state to (%d) - returning kIOReturnNotResponding", getName(), this, fromStr, (int)_powerStateChangingTo);
kr = kIOReturnNotResponding;
}
else if (_workLoop->onThread())
{
if (!_controllerAvailable)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall - call (%s) - onThread is true while !_controllerAvailable", getName(), this, fromStr);
kr = kIOReturnNotReady;
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, (int)_myPowerState, kr, 1 );
}
}
else if (_workLoop->inGate())
{
AbsoluteTime deadline;
IOCommandGate * commandGate = GetCommandGate();
if ( !commandGate )
{
USBLog(1,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall commandGate is NULL, returning kIOReturnNoMemory", getName(), this);
kr = kIOReturnNoMemory;
}
else
{
USBLog(5,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall inGate() is true, so commandSleep()'ing and waiting for our powerChange", getName(), this);
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, 0, 10 );
_inCheckPowerModeSleeping = true;
clock_interval_to_deadline(5, kSecondScale, &deadline);
IOReturn err = commandGate->commandSleep(&_inCheckPowerModeSleeping, deadline, THREAD_ABORTSAFE);
switch (err)
{
case THREAD_AWAKENED:
USBLog(6,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall commandSleep woke up normally (THREAD_AWAKENED) _myPowerState: %d", getName(), this, (uint32_t)_myPowerState );
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 4 );
kr = kIOReturnSuccess;
break;
case THREAD_TIMED_OUT:
USBLog(3,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall commandSleep timeout out (THREAD_TIMED_OUT) _myPowerState: %d", getName(), this, (uint32_t)_myPowerState );
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 5 );
_inCheckPowerModeSleeping = false;
kr = kIOReturnTimeout;
break;
case THREAD_INTERRUPTED:
USBLog(3,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall commandSleep interrupted (THREAD_INTERRUPTED) _myPowerState: %d", getName(), this, (uint32_t)_myPowerState );
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 6 );
_inCheckPowerModeSleeping = false;
kr = kIOReturnAborted;
break;
case THREAD_RESTART:
USBLog(3,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall commandSleep restarted (THREAD_RESTART) _myPowerState: %d", getName(), this, (uint32_t)_myPowerState);
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 7 );
_inCheckPowerModeSleeping = false;
kr = kIOReturnInternalError;
break;
case kIOReturnNotPermitted:
USBLog(3,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall woke up with status (kIOReturnNotPermitted) - we do not hold the WL!", getName(), this);
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 8 );
_inCheckPowerModeSleeping = false;
kr = kIOReturnNotPermitted;
break;
default:
USBLog(3,"IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall woke up with unknown status %p, _myPowerState: %d", getName(), this, (void*)kr, (uint32_t)_myPowerState);
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, _myPowerState, err, 9 );
_inCheckPowerModeSleeping = false;
kr = kIOReturnNotPermitted;
}
}
}
else
{
while ( (_myPowerState != kUSBPowerStateOn) and (retries-- > 0) )
{
#if 0
char* bt[8];
OSBacktrace((void**)bt, 8);
USBLog(4, "IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall - call (%s) while _myPowerState(%d) _controllerAvailable(%s) _powerStateChangingTo(%d) - sleeping thread, bt:[%p][%p][%p][%p][%p][%p][%p]", getName(), this, fromStr, (int)_myPowerState, _controllerAvailable ? "true" : "false", (int)_powerStateChangingTo, bt[1], bt[2], bt[3], bt[4], bt[5], bt[6], bt[7]);
#endif
IOSleep(10);
}
}
if ( retries < 1 )
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::CheckPowerModeBeforeGatedCall - call (%s) while _myPowerState(%d) _controllerAvailable (%s) - we could not wake up the controller, returning kIOReturnNotResponding", getName(), this, fromStr, (int)_myPowerState, _controllerAvailable ? "true" : "false");
kr = kIOReturnNotResponding;
USBTrace( kUSBTController, kTPControllerCheckPowerModeBeforeGatedCall, (uintptr_t)this, (int)_myPowerState, kr, 2 );
}
}
return kr;
}
IOReturn
IOUSBControllerV3::DoEnableAddressEndpoints(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
#pragma unused (arg2, arg3)
IOUSBControllerV3 *me = (IOUSBControllerV3 *)owner;
return me->UIMEnableAddressEndpoints((USBDeviceAddress)(uintptr_t)arg0, (bool)(uintptr_t) arg1);
}
IOReturn
IOUSBControllerV3::EnableAddressEndpoints(USBDeviceAddress address, bool enable)
{
IOCommandGate * commandGate = GetCommandGate();
return commandGate->runAction(DoEnableAddressEndpoints, (void*)(uintptr_t)address, (void*)enable);
}
IOReturn
IOUSBControllerV3::DoEnableAllEndpoints(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
#pragma unused (arg1, arg2, arg3)
IOUSBControllerV3 *me = (IOUSBControllerV3 *)owner;
return me->UIMEnableAllEndpoints((bool)(uintptr_t)arg0);
}
IOReturn
IOUSBControllerV3::EnableAllEndpoints(bool enable)
{
IOCommandGate * commandGate = GetCommandGate();
return commandGate->runAction(DoEnableAllEndpoints, (void*)enable);
}
void
IOUSBControllerV3::ControllerOff(void)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerOff - calling ResetControllerState", getName(), this);
ResetControllerState();
if (_expansionData && _watchdogUSBTimer && _watchdogTimerActive)
{
_watchdogUSBTimer->cancelTimeout(); _watchdogTimerActive = false;
}
}
void
IOUSBControllerV3::ControllerRestart(void)
{
ControllerOff();
}
void
IOUSBControllerV3::ControllerSleep(void)
{
if (_myPowerState == kUSBPowerStateLowPower)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerSleep - dozing now - need to wake controller from doze first", getName(), this);
WakeControllerFromDoze();
}
EnableInterruptsFromController(false);
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerSleep - calling SaveControllerStateForSleep", getName(), this);
SaveControllerStateForSleep();
}
void
IOUSBControllerV3::ControllerDoze(void)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerDoze", getName(), this);
switch(_myPowerState)
{
case kUSBPowerStateOff:
case kUSBPowerStateRestart:
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerDoze - OFF now - need to restart before dozing", getName(), this);
RestartControllerFromReset();
break;
case kUSBPowerStateSleep:
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerDoze - sleeping now - need to wake from sleep before dozing", getName(), this);
RestoreControllerStateFromSleep();
break;
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerDoze - calling DozeController", getName(), this);
DozeController();
}
void
IOUSBControllerV3::ControllerOn(void)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::ControllerOn - current state (%d) _ehciController(%p)", getName(), this, (int)_myPowerState, _ehciController);
UInt16 statusRegister = 0;
statusRegister = _device->configRead16(kIOPCIConfigStatus);
if ( statusRegister & kIOPCIStatusMasterAbortActive )
{
if ( gUSBStackDebugFlags & kUSBMasterAbortPanicMask )
{
panic("IOUSBControllerV3(%s)[%p] PCI Master Abort status is active\n", getName(), this);
}
else if ( gUSBStackDebugFlags & kUSBMasterAbortLoggingMask )
{
IOLog("IOUSBControllerV3(%s)[%p] PCI Master Abort status is active\n", getName(), this);
}
}
switch(_myPowerState)
{
case kUSBPowerStateOff:
case kUSBPowerStateRestart:
RestartControllerFromReset();
break;
case kUSBPowerStateSleep:
RestoreControllerStateFromSleep();
break;
case kUSBPowerStateLowPower:
WakeControllerFromDoze();
break;
}
}
bool
IOUSBControllerV3::IsControllerAvailable(void)
{
return _controllerAvailable;
}
IOReturn
IOUSBControllerV3::GatedPowerChange(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
#pragma unused (arg1, arg2, arg3)
IOUSBControllerV3 *me = (IOUSBControllerV3 *)owner;
unsigned long powerStateOrdinal = (unsigned long)arg0;
unsigned long oldState = me->_myPowerState;
USBTrace_Start( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, powerStateOrdinal, oldState, 0 );
switch (powerStateOrdinal)
{
case kUSBPowerStateOff:
me->ControllerOff();
break;
case kUSBPowerStateRestart:
me->ControllerRestart();
break;
case kUSBPowerStateSleep:
me->ControllerSleep();
break;
case kUSBPowerStateLowPower:
me->ControllerDoze();
break;
case kUSBPowerStateOn:
me->ControllerOn();
break;
}
me->_myPowerState = powerStateOrdinal;
if (powerStateOrdinal < kUSBPowerStateLowPower)
{
me->_controllerAvailable = false; me->RootHubStopTimer();
me->EnableBusMastering(false); }
else
{
me->_controllerAvailable = true;
if (oldState < kUSBPowerStateLowPower)
{
me->EnableInterruptsFromController(true);
if (me->_rootHubPollingRate32) me->RootHubStartTimer32(me->_rootHubPollingRate32); }
if ( me->_rootHubDevice == NULL )
{
IOReturn err;
if( (me->_expansionData) && (me->_controllerSpeed == kUSBDeviceSpeedSuper) )
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::GatedPowerChange - calling CreateRootHubDevice for SS Controller", me->getName(), me);
err = me->CreateRootHubDevice( me->_device, &(me->_rootHubDeviceSS) );
USBLog(5,"IOUSBControllerV3(%s)[%p]::GatedPowerChange - done with CreateRootHubDevice for SS - return (%p)", me->getName(), me, (void*)err);
if ( err != kIOReturnSuccess )
{
USBLog(1,"AppleUSBEHCI[%p]::GatedPowerChange - Could not create root hub device for SS upon wakeup (%x)!", me, err);
USBTrace( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, err, 0, 0 );
}
else
{
me->_rootHubDeviceSS->registerService(kIOServiceRequired | kIOServiceSynchronous);
}
}
USBLog(5, "IOUSBControllerV3(%s)[%p]::GatedPowerChange - calling CreateRootHubDevice", me->getName(), me);
err = me->CreateRootHubDevice( me->_device, &(me->_rootHubDevice) );
USBLog(5,"IOUSBControllerV3(%s)[%p]::GatedPowerChange - done with CreateRootHubDevice - return (%p)", me->getName(), me, (void*)err);
if ( err != kIOReturnSuccess )
{
USBLog(1,"AppleUSBEHCI[%p]::GatedPowerChange - Could not create root hub device upon wakeup (%x)!", me, err);
USBTrace( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, err, 0, 0 );
}
else
{
me->_rootHubDevice->registerService(kIOServiceRequired | kIOServiceSynchronous);
}
}
if (me->_expansionData && me->_watchdogUSBTimer && !me->_watchdogTimerActive)
{
me->_watchdogTimerActive = true;
me->_watchdogUSBTimer->setTimeoutMS(kUSBWatchdogTimeoutMS);
}
}
if ( powerStateOrdinal == kUSBPowerStateOn && me->_inCheckPowerModeSleeping )
{
IOCommandGate * commandGate = me->GetCommandGate();
if ( !commandGate )
{
USBLog(1,"IOUSBController::GatedPowerChange commandGate is NULL");
USBTrace( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, 0, 0, 1 );
}
else
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::GatedPowerChange - _inCheckPowerModeSleeping was true, calling commandWakeup", me->getName(), me);
commandGate->commandWakeup(&me->_inCheckPowerModeSleeping, false);
USBTrace( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, 0, 0, 2 );
me->_inCheckPowerModeSleeping = false;
}
}
USBTrace_End( kUSBTController, kTPControllerGatedPowerChange, (uintptr_t)me, me->_myPowerState, 0, 0);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::ChangeExternalDeviceCount(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
#pragma unused (arg1, arg2, arg3)
IOUSBControllerV3 *me = (IOUSBControllerV3 *)owner;
bool addDevice = (bool)arg0;
IOPMrootDomain *myRootDomain = me->getPMRootDomain();
if (myRootDomain && (kIOPMUndefinedDriverAssertionID != me->_externalUSBDeviceAssertionID))
{
if (addDevice)
{
if (me->_externalDeviceCount++ == 0)
{
if (myRootDomain)
{
USBLog(3, "IOUSBControllerV3(%s)[%p]::ChangeExternalDeviceCount - got first external device, changing assertion to ON", me->getName(), me);
myRootDomain->setPMAssertionLevel(me->_externalUSBDeviceAssertionID, kIOPMDriverAssertionLevelOn);
}
}
}
else
{
if (--(me->_externalDeviceCount) == 0)
{
if (myRootDomain)
{
USBLog(3, "IOUSBControllerV3(%s)[%p]::ChangeExternalDeviceCount - removed final external device, changing assertion to OFF", me->getName(), me);
myRootDomain->setPMAssertionLevel(me->_externalUSBDeviceAssertionID, kIOPMDriverAssertionLevelOff);
}
}
}
}
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
if (me->_externalDeviceCount < 0)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::ChangeExternalDeviceCount - count fell below 0!", me->getName(), me);
}
me->setProperty("External Device Count", me->_externalDeviceCount, 32);
#endif
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::HandlePowerChange(unsigned long powerStateOrdinal)
{
IOCommandGate * commandGate = GetCommandGate();
USBLog(5, "IOUSBControllerV3(%s)[%p]::HandlePowerChange - sending the state change request (%d) through the gate - configCommand(%p)", getName(), this, (int)powerStateOrdinal, (void*)_device->configRead16(kIOPCIConfigCommand));
return commandGate->runAction(GatedPowerChange, (void*)powerStateOrdinal);
}
IOReturn
IOUSBControllerV3::EnableBusMastering(bool enable)
{
UInt16 config = _device->configRead16(kIOPCIConfigCommand);
if (enable)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::EnableBusMastering(true) - currently (%p) - enabling", getName(), this, (void*)config);
config |= kIOPCICommandBusMaster;
}
else
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::EnableBusMastering(false) - currently (%p) - disabling", getName(), this, (void*)config);
config &= ~kIOPCICommandBusMaster;
}
_device->configWrite16(kIOPCIConfigCommand, config);
USBLog(5, "IOUSBControllerV3(%s)[%p]::EnableBusMastering - new value[%p]", getName(), this, (void*)_device->configRead16(kIOPCIConfigCommand));
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::EnsureUsability(void)
{
if (_rootHubDevice && _rootHubDevice->GetPolicyMaker())
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::EnsureUsability - passing on to root hub policy maker[%p]", getName(), this, _rootHubDevice->GetPolicyMaker());
_rootHubDevice->GetPolicyMaker()->EnsureUsability();
}
if (_rootHubDeviceSS && _rootHubDeviceSS->GetPolicyMaker())
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::EnsureUsability - passing on to root hub policy maker[%p]", getName(), this, _rootHubDeviceSS->GetPolicyMaker());
_rootHubDeviceSS->GetPolicyMaker()->EnsureUsability();
}
return kIOReturnSuccess;
}
void
IOUSBControllerV3::RootHubTimerFired(OSObject *owner, IOTimerEventSource *sender)
{
#pragma unused (sender)
IOUSBControllerV3 *me;
me = OSDynamicCast(IOUSBControllerV3, owner);
if (!me || me->isInactive() || !me->_controllerAvailable)
return;
if (me->_rootHubDevice && me->_rootHubDevice->GetPolicyMaker())
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired - PolicyMaker[%p] powerState[%d] _powerStateChangingTo[%d]", me->getName(), me, me->_rootHubDevice->GetPolicyMaker(), (int)me->_rootHubDevice->GetPolicyMaker()->getPowerState(),(int)me->_powerStateChangingTo);
if ((me->_powerStateChangingTo == kUSBPowerStateSleep) and (me->_rootHubDevice->GetPolicyMaker()->getPowerState() == kIOUSBHubPowerStateSleep))
{
USBLog(2, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired - abandoning ship because I am going to sleep and my root hub is already asleep", me->getName(), me);
return;
}
}
else
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired", me->getName(), me);
}
if (me->_rootHubDeviceSS && me->_rootHubDeviceSS->GetPolicyMaker())
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired - PolicyMaker[%p] powerState[%d] _powerStateChangingTo[%d]", me->getName(), me, me->_rootHubDeviceSS->GetPolicyMaker(), (int)me->_rootHubDeviceSS->GetPolicyMaker()->getPowerState(),(int)me->_powerStateChangingTo);
if ((me->_powerStateChangingTo == kUSBPowerStateSleep) and (me->_rootHubDeviceSS->GetPolicyMaker()->getPowerState() == kIOUSBHubPowerStateSleep))
{
USBLog(2, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired - abandoning ship because I am going to sleep and my root hub is already asleep", me->getName(), me);
return;
}
}
else
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::RootHubTimerFired", me->getName(), me);
}
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)me, (uintptr_t)me->_rootHubDevice->GetPolicyMaker(), (uintptr_t)me->_rootHubDevice->GetPolicyMaker()->getPowerState(), 4 );
me->CheckForRootHubChanges();
if (me->_rootHubPollingRate32 && !me->isInactive() && me->_controllerAvailable)
me->_rootHubTimer->setTimeoutMS(me->_rootHubPollingRate32);
}
void
IOUSBControllerV3::RHCompleteTransaction(IOUSBRootHubInterruptTransactionPtr outstandingRHTransPtr)
{
IOUSBRootHubInterruptTransaction xaction;
UInt8 bBitmap;
UInt16 wBitmap;
UInt8 bytesToMove;
UInt8* pBytes;
int i;
if (outstandingRHTransPtr[0].completion.action)
{
xaction = outstandingRHTransPtr[0];
for (i = 0; i < (kIOUSBMaxRootHubTransactions-1); i++)
{
outstandingRHTransPtr[i] = outstandingRHTransPtr[i+1];
}
outstandingRHTransPtr[kIOUSBMaxRootHubTransactions-1].completion.action = NULL;
if (_rootHubNumPorts < 8)
{
bytesToMove = 1;
bBitmap = (UInt8)_rootHubStatusChangedBitmap;
pBytes = &bBitmap;
}
else
{
bytesToMove = 2;
wBitmap = HostToUSBWord(_rootHubStatusChangedBitmap);
pBytes = (UInt8*)&wBitmap;
}
if (xaction.completion.action && xaction.buf)
{
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, 0, 0, 5 );
USBLog(6, "IOUSBControllerV3(%s)[%p]::RHCompleteTransaction - stopping timer and calling complete", getName(), this);
RootHubStopTimer();
_rootHubTransactionWasAborted = false;
xaction.buf->writeBytes(0, pBytes, bytesToMove);
Complete(xaction.completion, kIOReturnSuccess, xaction.bufLen - bytesToMove);
}
else
{
USBError(1, "IOUSBControllerV3(%s)[%p]::RHCompleteTransaction - NULL action(%p) or buf(%p)", getName(), this, xaction.completion.action, xaction.buf);
}
}
else
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::RHCompleteTransaction - no one is listening - i will try again later", getName(), this);
}
}
IOReturn
IOUSBControllerV3::CheckForRootHubChanges(void)
{
UIMRootHubStatusChange();
if (_rootHubStatusChangedBitmap)
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - got _rootHubStatusChangedBitmap(%p) isInactive(%s)", getName(), this, (void*)_rootHubStatusChangedBitmap, isInactive() ? "true" : "false");
if (_rootHubDevice)
{
if (_rootHubDevice->GetPolicyMaker())
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - making sure root hub driver AppleUSBHub[%p] is usable", getName(), this, _rootHubDevice->GetPolicyMaker());
_rootHubDevice->GetPolicyMaker()->EnsureUsability(); }
else
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - _rootHubStatusChangedBitmap(%p) for _rootHubDevice with no policy maker!!", getName(), this, (void*)_rootHubStatusChangedBitmap);
USBTrace( kUSBTController, kTPControllerCheckForRootHubChanges, (uintptr_t)this, _rootHubStatusChangedBitmap, 0, 0);
}
}
if (_rootHubDeviceSS)
{
if (_rootHubDeviceSS->GetPolicyMaker())
{
USBLog(5, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - making sure root hub driver SS AppleUSBHub[%p] is usable", getName(), this, _rootHubDeviceSS->GetPolicyMaker());
_rootHubDeviceSS->GetPolicyMaker()->EnsureUsability(); }
else
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - _rootHubStatusChangedBitmap(%p)for _rootHubDeviceSS with no policy maker!!", getName(), this, (void*)_rootHubStatusChangedBitmap);
USBTrace( kUSBTController, kTPControllerCheckForRootHubChanges, (uintptr_t)this, _rootHubStatusChangedBitmap, 0, 1);
}
}
if( _controllerSpeed == kUSBDeviceSpeedSuper )
{
UInt16 end = _rootHubPortsHSStartRange + _rootHubNumPortsHS - 1;
UInt16 start = _rootHubPortsHSStartRange;
UInt16 HSPortMap = ( _rootHubStatusChangedBitmap & USBBitRange(start,end) ) >> USBBitRangePhase(start,end);
HSPortMap <<= 1;
HSPortMap |= ( _rootHubStatusChangedBitmap & 0x1 );
end = _rootHubPortsSSStartRange + _rootHubNumPortsSS - 1;
start = _rootHubPortsSSStartRange;
UInt16 SSPortMap = ( _rootHubStatusChangedBitmap & USBBitRange(start,end) ) >> USBBitRangePhase(start,end);
SSPortMap <<= 1;
SSPortMap |= ( _rootHubStatusChangedBitmap & 0x1 );
USBLog(6, "IOUSBControllerV3(%s)[%p]::CheckForRootHubChanges - _rootHubStatusChangedBitmap(%p) HSPortMap(%p) SSPortMap(%p)", getName(), this, (void*)_rootHubStatusChangedBitmap, (void*)HSPortMap, (void*)SSPortMap);
if( HSPortMap > 0 )
{
_rootHubStatusChangedBitmap = HSPortMap;
RHCompleteTransaction(_outstandingRHTrans);
}
if( SSPortMap > 0 )
{
_rootHubStatusChangedBitmap = SSPortMap;
RHCompleteTransaction(_outstandingSSRHTrans);
}
}
else
{
RHCompleteTransaction(_outstandingRHTrans);
}
}
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::RHQueueTransaction(IOMemoryDescriptor *buf, UInt32 bufLen, IOUSBCompletion completion, IOUSBRootHubInterruptTransactionPtr outstandingRHXaction)
{
int i;
USBLog(6, "IOUSBControllerV3(%s)[%p]::RHQueueTransaction controllerSpeed: %d", getName(), this, _controllerSpeed);
for (i = 0; i < kIOUSBMaxRootHubTransactions; i++)
{
if (outstandingRHXaction[i].completion.action == NULL)
{
outstandingRHXaction[i].buf = buf;
outstandingRHXaction[i].bufLen = bufLen;
outstandingRHXaction[i].completion = completion;
if (i != 0)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::RHQueueTransaction - this is index(%d) - UNEXPECTED?", getName(), this, (int)i);
USBTrace( kUSBTController, kTPControllerRootHubQueueInterruptRead, (uintptr_t)this, i, 0, 0 );
break;
}
if ( _rootHubTransactionWasAborted )
{
USBLog(6, "IOUSBControllerV3(%s)[%p]::RHQueueTransaction _rootHubTransactionWasAborted was true, calling CheckForRootHubChanges()", getName(), this);
CheckForRootHubChanges();
}
return kIOReturnSuccess;
}
else
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::RHQueueTransaction we already had a completion.action for trans: %d, returning an error", getName(), this, i);
break;
}
}
return kIOReturnNotPermitted;
}
IOReturn
IOUSBControllerV3::RootHubQueueInterruptRead(IOMemoryDescriptor *buf, UInt32 bufLen, IOUSBCompletion completion)
{
IOReturn status = kIOReturnNotPermitted;
USBTrace_Start( kUSBTController, kTPControllerRootHubQueueInterruptRead, (uintptr_t)this, (uintptr_t)buf, bufLen, 0);
USBLog(6, "IOUSBControllerV3(%s)[%p]::RootHubQueueInterruptRead, starting timer", getName(), this);
RootHubStartTimer32(kUSBRootHubPollingRate);
IOUSBRootHubInterruptTransactionPtr outstandingRHXaction = _outstandingRHTrans;
if (_controllerSpeed == kUSBDeviceSpeedSuper)
{
UInt8 speed = 0;
UInt16 address = 0;
IOOptionBits options = buf->getTag();
speed = ((options & kUSBSpeed_Mask) >> kUSBSpeed_Shift);
address = ((options & kUSBAddress_Mask) >> kUSBAddress_Shift);
if (speed == kUSBDeviceSpeedSuper)
{
outstandingRHXaction = _outstandingSSRHTrans;
}
}
status = RHQueueTransaction(buf, bufLen, completion, outstandingRHXaction);
USBTrace_End( kUSBTController, kTPControllerRootHubQueueInterruptRead, (uintptr_t)this, status, bufLen, 0);
return status;
}
void
IOUSBControllerV3::RHAbortTransaction(IOUSBRootHubInterruptTransactionPtr outstandingRHXaction)
{
int i;
IOUSBRootHubInterruptTransaction xaction;
xaction = outstandingRHXaction[0];
if (xaction.completion.action)
{
for (i = 0; i < (kIOUSBMaxRootHubTransactions-1); i++)
{
outstandingRHXaction[i] = outstandingRHXaction[i+1];
}
outstandingRHXaction[kIOUSBMaxRootHubTransactions-1].completion.action = NULL;
Complete(xaction.completion, kIOReturnAborted, xaction.bufLen);
_rootHubTransactionWasAborted = true;
}
}
IOReturn
IOUSBControllerV3::RootHubAbortInterruptRead()
{
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, 0, 0, 3 );
USBLog(6, "IOUSBControllerV3(%s)[%p]::RootHubAbortInterruptRead, stopping timer", getName(), this);
RootHubStopTimer();
if( _controllerSpeed == kUSBDeviceSpeedSuper )
{
RHAbortTransaction(_outstandingSSRHTrans);
}
RHAbortTransaction(_outstandingRHTrans);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::RootHubStartTimer(UInt8 pollingRate)
{
#pragma unused (pollingRate)
USBLog(1,"IOUSBControllerV3(%s)[[%p]::RootHubStartTimer Obsolete method called", getName(), this);
return kIOReturnUnsupported;
}
IOReturn
IOUSBControllerV3::RootHubStartTimer32(uint32_t pollingRate)
{
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, pollingRate, 0, 1 );
if (pollingRate == 0)
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::RootHubStartTimer32 - invalid polling rate (%d)", getName(), this, pollingRate);
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, pollingRate, kIOReturnBadArgument, 6 );
return kIOReturnBadArgument;
}
_rootHubPollingRate32 = pollingRate;
if (_rootHubTimer)
{
USBLog(6, "IOUSBControllerV3(%s)[%p]::RootHubStartTimer32", getName(), this);
_rootHubTimer->setTimeoutMS(_rootHubPollingRate32);
}
else
{
USBLog(1, "IOUSBControllerV3(%s)[%p]::RootHubStartTimer32 - NO TIMER!!", getName(), this);
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, 0, kIOReturnSuccess, 7 );
}
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerV3::RootHubStopTimer(void)
{
USBTrace( kUSBTController, kTPControllerRootHubTimer, (uintptr_t)this, 0, 0, 2 );
USBLog(6, "IOUSBControllerV3(%s)[%p]::RootHubStopTimer", getName(), this);
if (_rootHubTimer)
{
_rootHubTimer->cancelTimeout();
}
return kIOReturnSuccess;
}
UInt32
IOUSBControllerV3::AllocateExtraRootHubPortPower(UInt32 extraPowerRequested)
{
#pragma unused (extraPowerRequested)
USBLog(1, "IOUSBControllerV3(%s)[%p]::AllocateExtraRootHubPortPower - DEPRECATED API called", getName(), this);
return 0;
}
void
IOUSBControllerV3::ReturnExtraRootHubPortPower(UInt32 extraPowerReturned)
{
#pragma unused (extraPowerReturned)
USBLog(1, "IOUSBControllerV3(%s)[%p]::ReturnExtraRootHubPortPower - DEPRECATED API called", getName(), this);
return;
}
IOReturn
IOUSBControllerV3::CheckPMAssertions(IOUSBDevice *forDevice, bool deviceBeingAdded)
{
UInt32 devInfo;
IOCommandGate * commandGate = GetCommandGate();
IOReturn ret = kIOReturnInternalError;
ret = forDevice->GetDeviceInformation(&devInfo);
if (!ret)
{
if ((devInfo & kUSBInformationDeviceIsInternalMask) == 0)
{
ret = commandGate->runAction(ChangeExternalDeviceCount, (void*)deviceBeingAdded);
}
}
return ret;
}
IOReturn
IOUSBControllerV3::GetRootHubBOSDescriptor(OSData *data)
{
#pragma unused (data)
return kIOReturnUnsupported;
}
IOReturn
IOUSBControllerV3::GetRootHub3Descriptor(IOUSB3HubDescriptor *desc)
{
#pragma unused (desc)
return kIOReturnUnsupported;
}
IOReturn
IOUSBControllerV3::GetRootHubPortErrorCount(UInt16 port, UInt16 *count)
{
#pragma unused (port, count)
return kIOReturnUnsupported;
}
IOReturn
IOUSBControllerV3::UIMDeviceToBeReset(short functionAddress)
{
#pragma unused (functionAddress)
return kIOReturnUnsupported;
}
IOReturn
IOUSBControllerV3::UIMAbortStream(UInt32 streamID,
short functionNumber,
short endpointNumber,
short direction)
{
if(streamID != kUSBAllStreams)
{
USBError(1, "IOUSBControllerV3(%s)[%p]::UIMAbortEndpoint - Stream version called for UIM which doesn't support it", getName(), this);
return kIOReturnUnsupported;
}
return UIMAbortEndpoint(functionNumber, endpointNumber, direction);
}
UInt32
IOUSBControllerV3::UIMMaxSupportedStream(void)
{
return(0);
}
IOReturn
IOUSBControllerV3::GetActualDeviceAddress(USBDeviceAddress currentAddress, USBDeviceAddress *newAddress)
{
IOCommandGate * commandGate = GetCommandGate();
return commandGate->runAction(DoGetActualDeviceAddress, (void*)(uintptr_t)currentAddress, (void*)newAddress);
}
IOReturn
IOUSBControllerV3::DoGetActualDeviceAddress(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
#pragma unused (arg2, arg3)
IOUSBControllerV3 * me = (IOUSBControllerV3 *)owner;
IOReturn kr = kIOReturnSuccess;
USBDeviceAddress * uimCurrentAddress = (USBDeviceAddress *)arg1;
*uimCurrentAddress = me->UIMGetActualDeviceAddress((USBDeviceAddress)(uintptr_t)arg0);
if ( *uimCurrentAddress == 0 )
{
kr = kIOReturnNotFound;
}
USBLog(6, "IOUSBControllerV3(%s)[%p]::DoGetActualDeviceAddress - uimCurrentAddress: %d, original: %d, returned 0x%x", me->getName(), me, *uimCurrentAddress, (USBDeviceAddress)(uintptr_t)arg0, (uint32_t)kr);
return kr;
}
IOReturn
IOUSBControllerV3::CreateStreams(UInt8 functionNumber, UInt8 endpointNumber, UInt8 direction, UInt32 maxStream)
{
IOCommandGate * commandGate = GetCommandGate();
return commandGate->runAction(DoCreateStreams, (void*)(uintptr_t)functionNumber, (void*)(uintptr_t)endpointNumber, (void*)(uintptr_t)direction, (void*)(uintptr_t)maxStream);
}
IOReturn
IOUSBControllerV3::DoCreateStreams(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
IOUSBControllerV3 * me = (IOUSBControllerV3 *)owner;
UInt8 functionNumber = (UInt8)(uintptr_t)arg0;
UInt8 endpointNumber = (UInt8)(uintptr_t)arg1;
UInt8 direction = (UInt8)(uintptr_t)arg2;
UInt32 maxStream = (UInt32)(uintptr_t)arg3;
USBLog(6, "IOUSBControllerV3(%s)[%p]::DoCreateStreams - functionNumber: %d, endpointNumber: %d, direction: %d, maxStream: %d", me->getName(), me, functionNumber, endpointNumber, direction, (uint32_t)maxStream);
return me->UIMCreateStreams(functionNumber, endpointNumber, direction, maxStream);
}
#pragma mark еееее IOUSBController methods еееее
IOReturn
IOUSBControllerV3::AcquireDeviceZero( void )
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall( (char *) "AcquireDeviceZero");
if ( kr != kIOReturnSuccess )
{
USBError(1, "IOUSBControllerV3(%s)[%p]::AcquireDeviceZero - CheckPowerModeBeforeGatedCall returned 0x%x", getName(), this, kr);
return kr;
}
return IOUSBController::AcquireDeviceZero();
}
void
IOUSBControllerV3::ReleaseDeviceZero( void )
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "ReleaseDeviceZero");
if ( kr != kIOReturnSuccess )
return;
return IOUSBController::ReleaseDeviceZero();
}
IOReturn
IOUSBControllerV3::DeviceRequest(IOUSBDevRequest *request, IOUSBCompletion *completion, USBDeviceAddress address, UInt8 epNum, UInt32 noDataTimeout, UInt32 completionTimeout)
{
IOReturn kr;
if ((_powerStateChangingTo == kUSBPowerStateStable) || (_powerStateChangingTo > kUSBPowerStateSleep))
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::DeviceRequest - current state (%d) _powerStateChangingTo(%d) - calling changePowerStateTo(4)", getName(), this, (int)_myPowerState, (int)_powerStateChangingTo);
changePowerStateTo(kUSBPowerStateOn);
}
kr = CheckPowerModeBeforeGatedCall((char *) "DeviceRequest");
if ( kr != kIOReturnSuccess )
return kr;
kr = IOUSBController::DeviceRequest(request, completion, address, epNum, noDataTimeout, completionTimeout);
if ((_powerStateChangingTo == kUSBPowerStateStable) || (_powerStateChangingTo > kUSBPowerStateSleep))
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::DeviceRequest done - current state (%d) - calling changePowerStateTo(3)", getName(), this, (int)_myPowerState);
changePowerStateTo(kUSBPowerStateLowPower);
}
return kr;
}
IOReturn
IOUSBControllerV3::DeviceRequest(IOUSBDevRequestDesc *request, IOUSBCompletion *completion, USBDeviceAddress address, UInt8 epNum, UInt32 noDataTimeout, UInt32 completionTimeout)
{
IOReturn kr;
USBLog(7, "IOUSBControllerV3(%s)[%p]::DeviceRequest - current state (%d) _powerStateChangingTo(%d) - calling changePowerStateTo(4)", getName(), this, (int)_myPowerState, (int)_powerStateChangingTo);
changePowerStateTo(kUSBPowerStateOn);
kr = CheckPowerModeBeforeGatedCall((char *) "DeviceRequest");
if ( kr != kIOReturnSuccess )
return kr;
kr = IOUSBController::DeviceRequest(request, completion, address, epNum, noDataTimeout, completionTimeout);
USBLog(7, "IOUSBControllerV3(%s)[%p]::DeviceRequest done - current state (%d) - calling changePowerStateTo(3)", getName(), this, (int)_myPowerState);
changePowerStateTo(kUSBPowerStateLowPower);
return kr;
}
IOReturn
IOUSBControllerV3::ClosePipe(USBDeviceAddress address, Endpoint *endpoint)
{
IOReturn kr;
if (!isInactive())
{
if (!(_controllerAvailable || _wakingFromHibernation || _restarting || _poweringDown))
{
kr = CheckPowerModeBeforeGatedCall((char *) "ClosePipe");
if ( kr != kIOReturnSuccess )
return kr;
}
}
return IOUSBController::ClosePipe(address, endpoint);
}
IOReturn
IOUSBControllerV3::AbortPipe(USBDeviceAddress address, Endpoint *endpoint)
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::AbortPipe - Deprecated version called (no stream ID)", getName(), this);
return AbortPipe(0, address, endpoint);
}
IOReturn
IOUSBControllerV3::AbortPipe(UInt32 streamID, USBDeviceAddress address, Endpoint *endpoint)
{
IOReturn kr;
if (!isInactive())
{
if (!(_controllerAvailable || _wakingFromHibernation || _restarting || _poweringDown))
{
kr = CheckPowerModeBeforeGatedCall((char *) "AbortPipe");
if ( kr != kIOReturnSuccess )
return kr;
}
}
return _commandGate->runAction(DoAbortStream, (void *)streamID, (void *)(UInt32) address,
(void *)(UInt32) endpoint->number, (void *)(UInt32) endpoint->direction);
}
IOReturn
IOUSBControllerV3::DoAbortStream(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3)
{
IOUSBControllerV3 *me = (IOUSBControllerV3 *)owner;
return me->UIMAbortStream((UInt32)(uintptr_t)arg0, (short)(uintptr_t) arg1, (short)(uintptr_t) arg2, (short)(uintptr_t) arg3);
}
IOReturn
IOUSBControllerV3::ResetPipe(USBDeviceAddress address, Endpoint *endpoint)
{
IOReturn kr;
if (!isInactive())
{
if (!(_controllerAvailable || _wakingFromHibernation || _restarting || _poweringDown))
{
kr = CheckPowerModeBeforeGatedCall((char *) "ResetPipe");
if ( kr != kIOReturnSuccess )
return kr;
}
}
return IOUSBController::ResetPipe(address, endpoint);
}
IOReturn
IOUSBControllerV3::ClearPipeStall(USBDeviceAddress address, Endpoint *endpoint)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "ClearPipeStall");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBController::ClearPipeStall(address, endpoint);
}
IOReturn
IOUSBControllerV3::Read(IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletion *completion, UInt32 noDataTimeout, UInt32 completionTimeout, IOByteCount reqCount)
{
return Read(0, buffer, address, endpoint, completion, noDataTimeout, completionTimeout, reqCount);
}
IOReturn
IOUSBControllerV3::Read(UInt32 streamID, IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletion *completion, UInt32 noDataTimeout, UInt32 completionTimeout, IOByteCount reqCount)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "Read");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBControllerV2::ReadStream(streamID, buffer, address, endpoint, completion, noDataTimeout, completionTimeout, reqCount);
}
IOReturn
IOUSBControllerV3::Write(IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletion *completion, UInt32 noDataTimeout, UInt32 completionTimeout, IOByteCount reqCount)
{
USBLog(7, "IOUSBControllerV3(%s)[%p]::Write deprecated method called (no stream ID)", getName(), this);
return Write(0, buffer, address, endpoint, completion, noDataTimeout, completionTimeout, reqCount);
}
IOReturn
IOUSBControllerV3::Write(UInt32 streamID, IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletion *completion, UInt32 noDataTimeout, UInt32 completionTimeout, IOByteCount reqCount)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "Write");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBControllerV2::WriteStream(streamID, buffer, address, endpoint, completion, noDataTimeout, completionTimeout, reqCount);
}
IOReturn
IOUSBControllerV3::IsocIO(IOMemoryDescriptor *buffer, UInt64 frameStart, UInt32 numFrames, IOUSBIsocFrame *frameList, USBDeviceAddress address, Endpoint *endpoint, IOUSBIsocCompletion *completion )
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "IsocIO");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBController::IsocIO(buffer, frameStart, numFrames, frameList, address, endpoint, completion);
}
IOReturn
IOUSBControllerV3::IsocIO(IOMemoryDescriptor *buffer, UInt64 frameStart, UInt32 numFrames, IOUSBLowLatencyIsocFrame *frameList, USBDeviceAddress address, Endpoint *endpoint, IOUSBLowLatencyIsocCompletion *completion, UInt32 updateFrequency )
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "IsocIO");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBController::IsocIO(buffer, frameStart, numFrames, frameList, address, endpoint, completion, updateFrequency);
}
#pragma mark еееее IOUSBControllerV2 methods еееее
IOReturn
IOUSBControllerV3::OpenPipe(USBDeviceAddress address, UInt8 speed, Endpoint *endpoint)
{
return OpenPipe(address, speed, endpoint, 0, 0);
}
IOReturn
IOUSBControllerV3::OpenPipe(USBDeviceAddress address, UInt8 speed, Endpoint *endpoint, UInt32 maxStreams, UInt32 maxBurstAndMult)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "OpenPipe");
if ( kr != kIOReturnSuccess )
return kr;
if( (maxStreams == 0) && (maxBurstAndMult == 0) )
{
return IOUSBControllerV2::OpenPipe(address, speed, endpoint);
}
else
{
return IOUSBControllerV2::OpenSSPipe(address, speed, endpoint, maxStreams, maxBurstAndMult);
}
}
IOReturn
IOUSBControllerV3::AddHSHub(USBDeviceAddress highSpeedHub, UInt32 flags)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "AddHSHub");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBControllerV2::AddHSHub(highSpeedHub, flags);
}
IOReturn
IOUSBControllerV3::RemoveHSHub(USBDeviceAddress highSpeedHub)
{
IOReturn kr;
if (!isInactive())
{
if (!(_controllerAvailable || _wakingFromHibernation || _restarting || _poweringDown))
{
kr = CheckPowerModeBeforeGatedCall((char *) "RemoveHSHub");
if ( kr != kIOReturnSuccess )
return kr;
}
}
return IOUSBControllerV2::RemoveHSHub(highSpeedHub);
}
IOReturn
IOUSBControllerV3::SetTestMode(UInt32 mode, UInt32 port)
{
IOReturn kr;
changePowerStateTo(kUSBPowerStateOn); kr = CheckPowerModeBeforeGatedCall((char *) "SetTestMode");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBControllerV2::SetTestMode(mode, port);
}
IOReturn
IOUSBControllerV3::ReadV2(IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletionWithTimeStamp *completion, UInt32 noDataTimeout, UInt32 completionTimeout, IOByteCount reqCount)
{
IOReturn kr;
kr = CheckPowerModeBeforeGatedCall((char *) "ReadV2");
if ( kr != kIOReturnSuccess )
return kr;
return IOUSBControllerV2::ReadV2(buffer, address, endpoint, completion, noDataTimeout, completionTimeout, reqCount);
}
enum
{
kNECuPD720101EXT1 = 0xE0, kNECuPD720101EXT1ID_WE = 0x80, kNECuPD720101PMC = 0x42 };
void
IOUSBControllerV3::FixupNECControllerConfigRegisters(void)
{
UInt32 ext1;
UInt16 pmc;
pmc = _device->configRead16(kNECuPD720101PMC);
if ( !(pmc & kPCIPMCPMESupportFromD3Cold) )
{
USBLog(2, "IOUSBControllerV3[%s][%p]::FixupNECControllerConfigRegisters - D3cold not set in PMC - changing", getName(), this);
ext1 = _device->configRead32(kNECuPD720101EXT1);
_device->configWrite32(kNECuPD720101EXT1, ext1 | kNECuPD720101EXT1ID_WE);
_device->configWrite16(kNECuPD720101PMC, pmc | kPCIPMCPMESupportFromD3Cold);
_device->configWrite32(kNECuPD720101EXT1, ext1);
}
}
USBDeviceAddress
IOUSBControllerV3::UIMGetActualDeviceAddress(USBDeviceAddress current)
{
#pragma unused(current)
return 0;
}
IOReturn
IOUSBControllerV3::UIMCreateSSBulkEndpoint(
UInt8 functionNumber,
UInt8 endpointNumber,
UInt8 direction,
UInt8 speed,
UInt16 maxPacketSize,
UInt32 maxStream,
UInt32 maxBurst)
{
#pragma unused (functionNumber, endpointNumber, direction, speed, maxPacketSize, maxStream, maxBurst)
return kIOReturnUnsupported; }
IOReturn
IOUSBControllerV3::UIMCreateSSInterruptEndpoint(
short functionAddress,
short endpointNumber,
UInt8 direction,
short speed,
UInt16 maxPacketSize,
short pollingRate,
UInt32 maxBurst)
{
#pragma unused (functionAddress, endpointNumber, direction, speed, maxPacketSize, pollingRate, maxBurst)
return kIOReturnUnsupported; }
IOReturn
IOUSBControllerV3::UIMCreateSSIsochEndpoint(
short functionAddress,
short endpointNumber,
UInt32 maxPacketSize,
UInt8 direction,
UInt8 interval,
UInt32 maxBurstAndMult)
{
#pragma unused (functionAddress, endpointNumber, maxPacketSize, direction, interval, maxBurstAndMult)
return kIOReturnUnsupported; }
IOReturn
IOUSBControllerV3::UIMCreateStreams(UInt8 functionNumber,
UInt8 endpointNumber,
UInt8 direction,
UInt32 maxStream)
{
#pragma unused (functionNumber)
#pragma unused (endpointNumber)
#pragma unused (direction)
#pragma unused (maxStream)
return kIOReturnUnsupported; }
IOReturn
IOUSBControllerV3::GetBandwidthAvailableForDevice(IOUSBDevice *forDevice, UInt32 *pBandwidthAvailable)
{
#pragma unused(forDevice)
UInt32 bandwidth;
IOReturn ret = kIOReturnSuccess;
USBLog(7, "IOUSBControllerV3(%s)[%p]::GetBandwidthAvailableForDevice - calling old method", getName(), this);
bandwidth = GetBandwidthAvailable();
*pBandwidthAvailable = bandwidth;
return ret;
}
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 0);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 1);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 2);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 3);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 4);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 5);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 6);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 7);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 8);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 9);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 10);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 11);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 12);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 13);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 14);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 15);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 16);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 17);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 18);
OSMetaClassDefineReservedUsed(IOUSBControllerV3, 19);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 20);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 21);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 22);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 23);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 24);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 25);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 26);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 27);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 28);
OSMetaClassDefineReservedUnused(IOUSBControllerV3, 29);