AppleUSBXHCI_PwrMgmt.cpp [plain text]
#include <IOKit/usb/IOUSBRootHubDevice.h>
#include <IOKit/usb/IOUSBHubPolicyMaker.h>
#include "AppleUSBXHCIUIM.h"
#ifndef XHCI_USE_KPRINTF
#define XHCI_USE_KPRINTF 0
#endif
#if XHCI_USE_KPRINTF
#undef USBLog
#undef USBError
void kprintf(const char *format, ...) __attribute__((format(printf, 1, 2)));
#define USBLog( LEVEL, FORMAT, ARGS... ) if ((LEVEL) <= XHCI_USE_KPRINTF) { kprintf( FORMAT "\n", ## ARGS ) ; }
#define USBError( LEVEL, FORMAT, ARGS... ) { kprintf( FORMAT "\n", ## ARGS ) ; }
#endif
#if (DEBUG_REGISTER_READS == 1)
#define Read32Reg(registerPtr, ...) Read32RegWithFileInfo(registerPtr, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define Read32RegWithFileInfo(registerPtr, function, file, line, ...) ( \
fTempReg = Read32Reg(registerPtr, ##__VA_ARGS__), \
fTempReg = (fTempReg == (typeof (*(registerPtr))) -1) ? \
(kprintf("AppleUSBXHCI[%p]::%s Invalid register at %s:%d %s\n", this,function,file, line,#registerPtr), -1) : fTempReg, \
(typeof(*(registerPtr)))fTempReg)
#define Read64Reg(registerPtr, ...) Read64RegWithFileInfo(registerPtr, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define Read64RegWithFileInfo(registerPtr, function, file, line, ...) ( \
fTempReg = Read64Reg(registerPtr, ##__VA_ARGS__), \
fTempReg = (fTempReg == (typeof (*(registerPtr))) -1) ? \
(kprintf("AppleUSBXHCI[%p]::%s Invalid register at %s:%d %s\n", this,function,file, line,#registerPtr), -1) : fTempReg, \
(typeof(*(registerPtr)))fTempReg)
#endif
#define super IOUSBControllerV3
#define _controllerCanSleep _expansionData->_controllerCanSleep
#pragma mark •••••••• Power Management ••••••••
void
AppleUSBXHCI::CheckSleepCapability(void)
{
USBLog(2, "AppleUSBXHCI[%p]::CheckSleepCapability - assuming that I can sleep", this);
_controllerCanSleep = true;
_hasPCIPwrMgmt = false;
if ( !_device->getProperty("AAPL,clock-id") )
{
if (_device->getProperty("built-in") || (_device->getProperty(kIOPCITunnelledKey) == kOSBooleanTrue))
{
if (_device->hasPCIPowerManagement(kPCIPMCPMESupportFromD3Cold) && (_device->enablePCIPowerManagement(kPCIPMCSPowerStateD3) == kIOReturnSuccess))
{
_hasPCIPwrMgmt = true;
setProperty("Card Type","Built-in");
}
}
else
{
if (_device->hasPCIPowerManagement() && (_device->enablePCIPowerManagement() == kIOReturnSuccess))
{
_hasPCIPwrMgmt = true;
setProperty("Card Type","Built-in");
}
}
if (!_hasPCIPwrMgmt)
{
USBError(1, "AppleUSBXHCI[%p]::CheckSleepCapability - controller will be unloaded across sleep",this);
_controllerCanSleep = false;
setProperty("Card Type","PCI");
}
}
else
{
setProperty("Card Type","Built-in");
}
}
IOReturn
AppleUSBXHCI::ResetControllerState(void)
{
IOReturn status = kIOReturnSuccess;
int i = 0;
USBLog(2, "AppleUSBXHCI[%p]::ResetControllerState (num interrupts: %d, num primary: %d, inactive:%d, unavailable:%d, is controller available:%d lost register access:%d)", this, (int)_numInterrupts, (int)_numPrimaryInterrupts, (int)_numInactiveInterrupts, (int)_numUnavailableInterrupts, (int)_controllerAvailable, (int)_lostRegisterAccess);
USBLog(2, "AppleUSBXHCI[%p]::ResetControllerState _myPowerState: %d _stateSaved %d", this, (uint32_t)_myPowerState, _stateSaved);
if(_lostRegisterAccess)
{
return(kIOReturnNotResponding);
}
else
{
status = StopUSBBus();
if( status != kIOReturnSuccess )
{
USBLog(1, "AppleUSBXHCI[%p]::ResetControllerState StopUSBBus returned: %x", this, (uint32_t)status);
return status;
}
_uimInitialized = false;
}
return(kIOReturnSuccess);
}
IOReturn
AppleUSBXHCI::RestartControllerFromReset(void)
{
USBLog(2, "AppleUSBXHCI[%p]::RestartControllerFromReset (num interrupts: %d, num primary: %d, inactive:%d, unavailable:%d, is controller available:%d lost register access:%d)", this, (int)_numInterrupts, (int)_numPrimaryInterrupts, (int)_numInactiveInterrupts, (int)_numUnavailableInterrupts, (int)_controllerAvailable, (int)_lostRegisterAccess);
USBLog(2, "AppleUSBXHCI[%p]::RestartControllerFromReset _myPowerState: %d _stateSaved %d", this, (uint32_t)_myPowerState, _stateSaved);
if (!_uimInitialized)
{
IOReturn status = ResetController();
if( status != kIOReturnSuccess )
{
USBLog(2, "AppleUSBXHCI[%p]::RestartControllerFromReset ResetController returned 0x%x", this, status);
return status;
}
UInt8 portIndex = 0, deviceIndex = 0;
for ( portIndex=1; portIndex<=_rootHubNumPorts; portIndex++ )
{
UInt32 portSC = Read32Reg(&_pXHCIRegisters->PortReg[portIndex-1].PortSC);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (portSC & kXHCIPortSC_WRC)
{
portSC |= (UInt32) kXHCIPortSC_WRC;
Write32Reg(&_pXHCIRegisters->PortReg[portIndex-1].PortSC, portSC);
IOSync();
}
if ((portSC & kXHCIPortSC_CCS) && !(portSC & kXHCIPortSC_CSC))
{
USBLog(1, "AppleUSBXHCI[%p]::UIMInitialize - PortReg[%d].PortSC: 0x%08x, has a CCS but no CSC", this, portIndex-1, (uint32_t)portSC);
_synthesizeCSC[portIndex-1] = true;
}
}
EnableXHCIPorts();
_stateSaved = false;
UInt16 slot, endp;
XHCIRing *ring = NULL;
for( slot = 0; slot < _numDeviceSlots; slot++ )
{
if( _slots[slot].buffer != NULL )
{
for( endp = 1; endp < kXHCI_Num_Contexts; endp++ )
{
ring = GetRing(slot, endp, 0);
if(IsStreamsEndpoint(slot, endp))
{
if( _slots[slot].maxStream[endp] != 0 )
{
for( UInt16 streamsID = 1; streamsID <= _slots[slot].maxStream[endp]; streamsID++ )
{
XHCIRing *streamsRing = GetRing(slot, endp, streamsID);
if(streamsRing != NULL)
{
DeallocRing(streamsRing);
}
}
}
}
if( ring != NULL )
{
DeallocRing(ring);
IOFree(ring, sizeof(XHCIRing)* (_slots[slot].maxStream[endp]+1));
_slots[slot].potentialStreams[endp] = 0;
_slots[slot].maxStream[endp] = 0;
_slots[slot].rings[endp] = NULL;
}
}
_slots[slot].deviceContext = NULL;
_slots[slot].deviceContext64 = NULL;
_slots[slot].buffer->complete();
_slots[slot].buffer->release();
_slots[slot].buffer = 0;
_slots[slot].deviceContextPhys = 0;
}
}
for ( deviceIndex = 0; deviceIndex < kMaxDevices; deviceIndex++ )
{
_devHub[deviceIndex] = 0;
_devPort[deviceIndex] = 0;
_devMapping[deviceIndex] = 0;
_devEnabled[deviceIndex] = false;
}
for ( portIndex = 0 ; portIndex < kMaxPorts; portIndex++ )
{
_prevSuspend[portIndex] = false;
_suspendChangeBits[portIndex] = false;
}
UInt32 configReg = Read32Reg(&_pXHCIRegisters->Config);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
configReg = (configReg & ~kXHCINumDevsMask) | _numDeviceSlots;
Write32Reg(&_pXHCIRegisters->Config, configReg);
Write32Reg(&_pXHCIRegisters->DNCtrl, 0xFFFF);
USBLog(3, "AppleUSBXHCI[%p]::RestartControllerFromReset - DCBAA - pPhysical[%p] pLogical[%p]", this, (void*)_DCBAAPhys, _DCBAA);
Write64Reg(&_pXHCIRegisters->DCBAAP, _DCBAAPhys);
USBLog(3, "AppleUSBXHCI[%p]::RestartControllerFromReset - CMD Ring - pPhysical[%p] pLogical[%p], num CMDs: %d", this, (void*)_CMDRingPhys, _CMDRing, _numCMDs);
InitCMDRing();
USBLog(3, "AppleUSBXHCI[%p]::RestartControllerFromReset - _ERSTMax %d", this, _ERSTMax);
USBLog(3, "AppleUSBXHCI[%p]::RestartControllerFromReset - Event Ring %d - pPhysical[%p] pLogical[%p], num Events: %d", this, kPrimaryInterrupter, (void*)_events[kPrimaryInterrupter].EventRingPhys, _events[kPrimaryInterrupter].EventRing, _events[kPrimaryInterrupter].numEvents);
InitEventRing(kPrimaryInterrupter, true);
USBLog(3, "AppleUSBXHCI[%p]::RestartControllerFromReset - Event Ring %d - pPhysical[%p] pLogical[%p], num Events: %d", this, kTransferInterrupter, (void*)_events[kTransferInterrupter].EventRingPhys, _events[kTransferInterrupter].EventRing, _events[kTransferInterrupter].numEvents);
InitEventRing(kTransferInterrupter, true);
if(_numScratchpadBufs != 0)
{
_DCBAA[0] = _SBAPhys;
}
_CCEPhysZero = 0;
_CCEBadIndex = 0;
_EventChanged = 0;
_IsocProblem = 0;
_stateSaved = false;
_fakedSetaddress = false;
_filterInterruptActive = false;
_frameNumber64 = 0;
_numInterrupts = 0;
_numPrimaryInterrupts = 0;
_numInactiveInterrupts = 0;
_numUnavailableInterrupts = 0;
_uimInitialized = true;
}
return(kIOReturnSuccess);
}
void AppleUSBXHCI::SaveAnInterrupter(int IRQ)
{
_savedInterrupter[IRQ].ERSTSZ = Read32Reg(&_pXHCIRuntimeReg->IR[IRQ].ERSTSZ);
_savedInterrupter[IRQ].ERSTBA = Read64Reg(&_pXHCIRuntimeReg->IR[IRQ].ERSTBA);
_savedInterrupter[IRQ].ERDP = Read64Reg(&_pXHCIRuntimeReg->IR[IRQ].ERDP);
_savedInterrupter[IRQ].IMAN = Read32Reg(&_pXHCIRuntimeReg->IR[IRQ].IMAN);
_savedInterrupter[IRQ].IMOD = Read32Reg(&_pXHCIRuntimeReg->IR[IRQ].IMOD);
}
void AppleUSBXHCI::RestoreAnInterrupter(int IRQ)
{
Write32Reg(&_pXHCIRuntimeReg->IR[IRQ].ERSTSZ, _savedInterrupter[IRQ].ERSTSZ);
Write64Reg(&_pXHCIRuntimeReg->IR[IRQ].ERSTBA, _savedInterrupter[IRQ].ERSTBA);
Write64Reg(&_pXHCIRuntimeReg->IR[IRQ].ERDP, _savedInterrupter[IRQ].ERDP);
Write32Reg(&_pXHCIRuntimeReg->IR[IRQ].IMAN, _savedInterrupter[IRQ].IMAN);
Write32Reg(&_pXHCIRuntimeReg->IR[IRQ].IMOD, _savedInterrupter[IRQ].IMOD);
}
IOReturn
AppleUSBXHCI::SaveControllerStateForSleep(void)
{
USBLog(2, "AppleUSBXHCI[%p]::SaveControllerStateForSleep _myPowerState: %d", this, (uint32_t)_myPowerState);
IOReturn status = kIOReturnSuccess;
UInt32 CMD, count=0;
status = StopUSBBus();
if( status != kIOReturnSuccess )
{
USBLog(1, "AppleUSBXHCI[%p]::SaveControllerStateForSleep StopUSBBus returned: %x", this, (uint32_t)status);
return status;
}
_savedRegisters.USBCMD = Read32Reg(&_pXHCIRegisters->USBCMD);
_savedRegisters.DNCtrl = Read32Reg(&_pXHCIRegisters->DNCtrl);
_savedRegisters.DCBAAP = Read64Reg(&_pXHCIRegisters->DCBAAP);
_savedRegisters.Config = Read32Reg(&_pXHCIRegisters->Config);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
SaveAnInterrupter(kPrimaryInterrupter);
SaveAnInterrupter(kTransferInterrupter);
CMD = Read32Reg(&_pXHCIRegisters->USBCMD);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
CMD |= kXHCICMDCSS;
Write32Reg(&_pXHCIRegisters->USBCMD, CMD);
count = 0;
UInt32 usbSts = Read32Reg(&_pXHCIRegisters->USBSTS);
while((!_lostRegisterAccess) && (usbSts & kXHCISSS))
{
IOSleep(1);
if(count++ >100)
{
USBLog(1, "AppleUSBXHCI[%p]::SaveControllerStateForSleep - Controller not saved state after 100ms", this);
return (kIOReturnInternalError);
}
usbSts = Read32Reg(&_pXHCIRegisters->USBSTS);
}
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
usbSts = Read32Reg(&_pXHCIRegisters->USBSTS);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if(usbSts & kXHCISRE)
{
USBLog(1, "AppleUSBXHCI[%p]::SaveControllerStateForSleep - Error saving controller state", this);
return (kIOReturnInternalError);
}
_stateSaved = true;
USBLog(2, "AppleUSBXHCI[%p]::SaveControllerStateForSleep - state saved", this);
PrintRuntimeRegs();
return kIOReturnSuccess;
}
IOReturn
AppleUSBXHCI::RestoreControllerStateFromSleep(void)
{
int slot, endp;
UInt32 CMD, STS, count=0;
UInt32 portIndex;
volatile UInt32 val = 0;
volatile UInt32 * addr;
USBLog(2, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep _myPowerState: %d _stateSaved %d", this, (uint32_t)_myPowerState, _stateSaved);
PrintRuntimeRegs();
UInt32 sts = Read32Reg(&_pXHCIRegisters->USBSTS);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (sts & kXHCIPCD)
{
UInt32 port;
for (port=0; port < _rootHubNumPorts; port++)
{
UInt32 portSC = Read32Reg(&_pXHCIRegisters->PortReg[port].PortSC);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (portSC & kXHCIPortSC_CSC)
{
if (portSC & kXHCIPortSC_PED)
{
USBError(1, "USB (XHCI):Port %d on bus 0x%x - connect status changed but still enabled. clearing enable bit: portSC(0x%x)\n", (int)port+1, (uint32_t)_busNumber, (uint32_t)portSC);
portSC = GetPortSCForWriting(port+1);
portSC |= (UInt32)kXHCIPortSC_PEC;
Write32Reg(&_pXHCIRegisters->PortReg[port].PortSC, portSC);
}
else
{
IOLog("USB (%s):Port %d on bus 0x%x connected or disconnected: portSC(0x%x)\n", _rootHubDevice ? _rootHubDevice->getName() : "XHCI", (int)port+1, (uint32_t)_busNumber, (uint32_t)portSC);
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x (%s)- connected or disconnected, calling EnsureUsability()", this, (int)port+1, (uint32_t)_busNumber, _rootHubDevice ? _rootHubDevice->getName() : "XHCI");
EnsureUsability();
}
}
else if ( ((portSC & kXHCIPortSC_LinkState_Mask) >> kXHCIPortSC_LinkState_Shift) == kXHCIPortSC_PLS_Resume)
{
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x - has remote wakeup from some device", this, (int)port+1, (uint32_t)_busNumber);
if (_rootHubDevice && _rootHubDevice->GetPolicyMaker())
{
_rootHubDevice->GetPolicyMaker()->message(kIOUSBMessageRootHubWakeEvent, this, (void *)(uintptr_t) port);
}
else
{
IOLog("\tUSB (XHCI):Port %d on bus 0x%x has remote wakeup from some device\n", (int)port+1, (uint32_t)_busNumber);
}
portSC = GetPortSCForWriting(port+1);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
portSC |= (UInt32)kXHCIPortSC_PLC;
Write32Reg(&_pXHCIRegisters->PortReg[port].PortSC, portSC);
}
else if (portSC & kXHCIPortSC_PED)
{
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x is enabled but not handling portSC of 0x%x", this, (int)port+1, (uint32_t)_busNumber, (uint32_t)portSC);
}
}
}
if(_stateSaved)
{
USBLog(2, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - restoring saved state", this);
Write32Reg(&_pXHCIRegisters->USBCMD, _savedRegisters.USBCMD);
Write32Reg(&_pXHCIRegisters->DNCtrl, _savedRegisters.DNCtrl);
Write64Reg(&_pXHCIRegisters->DCBAAP, _savedRegisters.DCBAAP);
Write32Reg(&_pXHCIRegisters->Config, _savedRegisters.Config);
RestoreAnInterrupter(kPrimaryInterrupter);
RestoreAnInterrupter(kTransferInterrupter);
CMD = Read32Reg(&_pXHCIRegisters->USBCMD);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
CMD |= kXHCICMDCRS;
Write32Reg(&_pXHCIRegisters->USBCMD, CMD);
count = 0;
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
while((!_lostRegisterAccess) && (STS & kXHCIRSS))
{
IOSleep(1);
if(count++ >100)
{
USBLog(1, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - Controller state not restored after 100ms", this);
break ;
}
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
}
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
InitCMDRing();
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if(STS & kXHCISRE)
{
int i;
USBLog(1, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - Error restoring controller state USBSTS = 0x%x", this, STS);
Write32Reg(&_pXHCIRuntimeReg->IR[kPrimaryInterrupter].IMAN, 0); Write32Reg(&_pXHCIRuntimeReg->IR[kTransferInterrupter].IMAN, 0); Write32Reg(&_pXHCIRegisters->USBCMD, 0); IOSync();
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
for (i=0; (!_lostRegisterAccess) && (i < 100) && !(STS & kXHCIHCHaltedBit); i++)
{
IOSleep(1);
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
}
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (i >= 100)
{
USBError(1, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - could not get chip to halt within 100 ms", this);
return(kIOReturnInternalError);
}
}
_stateSaved = false;
}
STS = Read32Reg(&_pXHCIRegisters->USBSTS);
if( (STS & kXHCIHCHaltedBit) || (STS & kXHCIHSEBit) )
{
}
DisableComplianceMode();
for(slot = 0; slot<_numDeviceSlots; slot++)
{
if(_slots[slot].buffer != NULL)
{
for(endp = 1; endp<kXHCI_Num_Contexts; endp++)
{
XHCIRing *ring;
ring = GetRing(slot, endp, 0);
if( (ring != NULL) && (ring->TRBBuffer != NULL) )
{
if(IsStreamsEndpoint(slot, endp))
{
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - restart stream ep=%d", this, endp);
RestartStreams(slot, endp, 0);
}
else
{
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep - slot=%d doorbell4ep=%d", this, slot, endp);
StartEndpoint(slot, endp);
}
}
}
}
}
for (portIndex=0; portIndex < _rootHubNumPorts; portIndex++)
{
UInt32 portSC;
portSC = Read32Reg(&_pXHCIRegisters->PortReg[portIndex].PortSC);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (portSC & kXHCIPortSC_CAS)
{
USBLog(5, "AppleUSBXHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x has CAS bit set (0x%08x), issuing a Warm Reset", this, (int)portIndex+1, (uint32_t)_busNumber, (uint32_t)portSC);
portSC = GetPortSCForWriting(portIndex+1);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
portSC |= (UInt32)kXHCIPortSC_WPR;
Write32Reg(&_pXHCIRegisters->PortReg[portIndex].PortSC, portSC);
IOSync();
IOSleep(50);
}
}
return kIOReturnSuccess;
}
enum {
SWAXHCIReg = 0x40, SWAXHCIValue = 0x800 };
IOReturn
AppleUSBXHCI::DozeController(void)
{
USBLog(2, "AppleUSBXHCI[%p]::DozeController _myPowerState: %d, _externalDeviceCount %d", this, (uint32_t)_myPowerState, (int)_v3ExpansionData->_externalDeviceCount);
return kIOReturnSuccess;
}
IOReturn
AppleUSBXHCI::WakeControllerFromDoze(void)
{
int i;
UInt32 port;
bool somePortNeedsToResume = false;
USBLog(2, "AppleUSBXHCI[%p]::WakeControllerFromDoze _myPowerState: %d", this, (uint32_t)_myPowerState);
for (port = 0; port < _rootHubNumPorts; port++)
{
UInt32 PLS, portSC;
portSC = Read32Reg(&_pXHCIRegisters->PortReg[port].PortSC);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
PLS = (UInt32)(portSC & kXHCIPortSC_LinkState_Mask) >> kXHCIPortSC_LinkState_Shift;
if (PLS == kXHCIPortSC_PLS_Resume)
{
USBLog(5, "AppleUSBXHCI[%p]::WakeControllerFromDoze - port %d appears to be resuming from a remote wakeup", this, (int)port+1);
_rhPortBeingResumed[port] = true;
somePortNeedsToResume = true;
}
}
if ( somePortNeedsToResume )
{
IOSleep(20);
RHCompleteResumeOnAllPorts();
}
return kIOReturnSuccess;
}
IOReturn
AppleUSBXHCI::EnableInterruptsFromController(bool enable)
{
UInt32 CMD = Read32Reg(&_pXHCIRegisters->USBCMD);
USBLog(2, "AppleUSBXHCI[%p]::EnableInterruptsFromController (num interrupts: %d, num primary: %d, inactive:%d, unavailable:%d, is controller available:%d lost register access:%d)", this, (int)_numInterrupts, (int)_numPrimaryInterrupts, (int)_numInactiveInterrupts, (int)_numUnavailableInterrupts, (int)_controllerAvailable, (int)_lostRegisterAccess);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if (enable)
{
USBLog(2, "AppleUSBXHCI[%p]::EnableInterruptsFromController - enabling interrupts, USBCMD(%p) INTE(%s)", this, (void*)CMD,
(CMD & kXHCICMDINTE) ? "true":"false" );
RestartUSBBus();
}
else
{
CMD &= ~kXHCICMDINTE;
Write32Reg(&_pXHCIRegisters->USBCMD, CMD);
IOSync();
USBLog(2, "AppleUSBXHCI[%p]::EnableInterruptsFromController - interrupts disabled, USBCMD(%p) INTE(%s)", this, (void*)CMD,
(CMD & kXHCICMDINTE) ? "true":"false" );
}
return kIOReturnSuccess;
}
IOReturn
AppleUSBXHCI::QuiesceAllEndpoints ( )
{
IOReturn ret = kIOPMAckImplied;
int slot, endp;
USBLog(5, "AppleUSBXHCI[%p]::QuiesceAllEndpoints", this);
if( (_errataBits & kXHCIErrataPPT) != 0 )
{
int portIndex = 0;
for (portIndex=0; portIndex < _rootHubNumPorts; portIndex++ )
{
UInt32 portSC = Read32Reg(&_pXHCIRegisters->PortReg[portIndex].PortSC);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if ( !(portSC & kXHCIPortSC_CSC) )
{
portSC = GetPortSCForWriting(portIndex+1);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
portSC |= (UInt32) kXHCIPortSC_CSC;
Write32Reg(&_pXHCIRegisters->PortReg[portIndex].PortSC, portSC);
IOSync();
}
}
}
for(slot = 0; slot<_numDeviceSlots; slot++)
{
if(_slots[slot].buffer != NULL)
{
for(endp = 1; endp<kXHCI_Num_Contexts; endp++)
{
XHCIRing *ring;
ring = GetRing(slot, endp, 0);
if( (ring != NULL) && (ring->TRBBuffer != NULL) )
{
USBLog(1, "AppleUSBXHCI[%p]::QuiesceAllEndpoints calling QuiesceEndpoint = %d, %d ", this, slot, endp);
QuiesceEndpoint(slot, endp);
}
}
}
}
int commandRingRunning = (int)Read64Reg(&_pXHCIRegisters->CRCR);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
if( commandRingRunning & kXHCI_CRR )
{
int count = 0;
Write64Reg(&_pXHCIRegisters->CRCR, (_CMDRingPhys & ~kXHCICRCRFlags_Mask) | kXHCI_CS);
_waitForCommandRingStoppedEvent = true;
while (_waitForCommandRingStoppedEvent)
{
USBLog(1, "AppleUSBXHCI[%p]::QuiesceAllEndpoints waiting for command ring stop, count = %d", this, count);
PollForCMDCompletions(kPrimaryInterrupter);
if (_lostRegisterAccess)
{
return kIOReturnNoDevice;
}
count++;
if ( count > 100 )
break;
IOSleep(1);
}
}
return (ret);
}
void
AppleUSBXHCI::ControllerSleep ( void )
{
USBLog(5, "AppleUSBXHCI[%p]::ControllerSleep", this);
if(_myPowerState == kUSBPowerStateLowPower)
WakeControllerFromDoze();
QuiesceAllEndpoints();
EnableInterruptsFromController(false);
SaveControllerStateForSleep();
}
void
AppleUSBXHCI::powerChangeDone ( unsigned long fromState)
{
unsigned long newState = getPowerState();
USBLog((fromState == newState) || !_controllerAvailable ? 7 : 4, "AppleUSBXHCI[%p]::powerChangeDone from state (%d) to state (%d) _controllerAvailable(%s)", this, (int)fromState, (int)newState, _controllerAvailable ? "true" : "false");
if (_wakingFromHibernation)
{
USBLog(5, "AppleUSBXHCI[%p]::powerChangeDone - _wakingFromHibernation is set", this);
}
super::powerChangeDone(fromState);
}