AppleUSBOHCI_RootHub.cpp [plain text]
extern "C" {
#include <kern/clock.h>
}
#include <IOKit/usb/USB.h>
#include <IOKit/usb/IOUSBLog.h>
#include <libkern/OSByteOrder.h>
#include "AppleUSBOHCI.h"
#ifndef APPLEOHCIROOTHUB_USE_KPRINTF
#define APPLEOHCIROOTHUB_USE_KPRINTF 0
#endif
#if APPLEOHCIROOTHUB_USE_KPRINTF
#undef USBLog
#undef USBError
void kprintf(const char *format, ...)
__attribute__((format(printf, 1, 2)));
#define USBLog( LEVEL, FORMAT, ARGS... ) if ((LEVEL) <= 5) { kprintf( FORMAT "\n", ## ARGS ) ; }
#define USBError( LEVEL, FORMAT, ARGS... ) { kprintf( FORMAT "\n", ## ARGS ) ; }
#endif
#define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme
#define super IOUSBController
enum {
kAppleVendorID = 0x05AC,
kPrdRootHubApple = 0x8005,
kOHCIRootHubPollingInterval = 32 };
IOReturn AppleUSBOHCI::GetRootHubDeviceDescriptor(IOUSBDeviceDescriptor *desc)
{
IOUSBDeviceDescriptor newDesc =
{
sizeof(IOUSBDeviceDescriptor), kUSBDeviceDesc, USB_CONSTANT16(kUSBRel10), kUSBHubClass, kUSBHubSubClass, 0, 8, USB_CONSTANT16(kAppleVendorID), USB_CONSTANT16(kPrdRootHubApple), USB_CONSTANT16(0x0190), 2, 1, 0, 1 };
if (!desc)
return(kIOReturnNoMemory);
bcopy(&newDesc, desc, newDesc.bLength);
return(kIOReturnSuccess);
}
IOReturn AppleUSBOHCI::GetRootHubDescriptor(IOUSBHubDescriptor *desc)
{
IOUSBHubDescriptor hubDesc;
UInt8 pps, nps, cd, ppoc, noc;
UInt32 descriptorA, descriptorB, data;
UInt8 *dstP;
unsigned int i, numBytes;
descriptorA = USBToHostLong(_pOHCIRegisters->hcRhDescriptorA);
descriptorB = USBToHostLong(_pOHCIRegisters->hcRhDescriptorB);
hubDesc.length = sizeof(IOUSBHubDescriptor);
hubDesc.hubType = kUSBHubDescriptorType;
hubDesc.numPorts = ((descriptorA & kOHCIHcRhDescriptorA_NDP)
>> kOHCIHcRhDescriptorA_NDPPhase);
pps = (descriptorA & kOHCIHcRhDescriptorA_PSM) ? 1 : 0;
nps = (descriptorA & kOHCIHcRhDescriptorA_NPS) ? 1 : 0;
cd = (descriptorA & kOHCIHcRhDescriptorA_DT) ? 1 : 0;
ppoc = (descriptorA & kOHCIHcRhDescriptorA_OCPM) ? 1 : 0;
noc = (descriptorA & kOHCIHcRhDescriptorA_NOCP) ? 1 : 0;
hubDesc.characteristics = 0;
hubDesc.characteristics |= (pps ? kPerPortSwitchingBit : 0);
hubDesc.characteristics |= (nps ? kNoPowerSwitchingBit : 0);
hubDesc.characteristics |= (cd ? kCompoundDeviceBit : 0);
hubDesc.characteristics |= (ppoc ? kPerPortOverCurrentBit : 0);
hubDesc.characteristics |= (noc ? kNoOverCurrentBit : 0);
hubDesc.characteristics = HostToUSBWord(hubDesc.characteristics);
hubDesc.powerOnToGood = ((descriptorA & kOHCIHcRhDescriptorA_POTPGT)
>> kOHCIHcRhDescriptorA_POTPGTPhase);
hubDesc.hubCurrent = 0;
numBytes = (hubDesc.numPorts + 1) / 8 + 1;
dstP = (UInt8 *)&hubDesc.removablePortFlags[0];
data = (descriptorB & kOHCIHcRhDescriptorB_DR) >> kOHCIHcRhDescriptorB_DRPhase;
for (i=0; i<numBytes; i++) {
*dstP++ = (UInt8)data;
data >>= 8;
}
data = (descriptorB & kOHCIHcRhDescriptorB_PPCM) >> kOHCIHcRhDescriptorB_PPCMPhase;
for (i=0; i<numBytes; i++) {
*dstP++ = (UInt8)data;
data >>= 8;
}
hubDesc.length -= ((sizeof(hubDesc.removablePortFlags) - numBytes) +
(sizeof(hubDesc.pwrCtlPortFlags) - numBytes));
if (!desc)
return(kIOReturnNoMemory);
bcopy(&hubDesc, desc, hubDesc.length);
return(kIOReturnSuccess);
}
IOReturn AppleUSBOHCI::GetRootHubConfDescriptor(OSData *desc)
{
IOUSBConfigurationDescriptor confDesc =
{
sizeof(IOUSBConfigurationDescriptor), kUSBConfDesc, USB_CONSTANT16(sizeof(IOUSBConfigurationDescriptor) +
sizeof(IOUSBInterfaceDescriptor) +
sizeof(IOUSBEndpointDescriptor)), 1, 1, 0, 0x60, 0, };
IOUSBInterfaceDescriptor intfDesc =
{
sizeof(IOUSBInterfaceDescriptor), kUSBInterfaceDesc, 0, 0, 1, kUSBHubClass, kUSBHubSubClass, 0, 0 };
IOUSBEndpointDescriptor endptDesc =
{
sizeof(IOUSBEndpointDescriptor), kUSBEndpointDesc, 0x81, kUSBInterrupt, USB_CONSTANT16(8), 255, };
if (!desc)
return(kIOReturnNoMemory);
if (!desc->appendBytes(&confDesc, confDesc.bLength))
return(kIOReturnNoMemory);
if (!desc->appendBytes(&intfDesc, intfDesc.bLength))
return(kIOReturnNoMemory);
if (!desc->appendBytes(&endptDesc, endptDesc.bLength))
return(kIOReturnNoMemory);
return(kIOReturnSuccess);
}
IOReturn AppleUSBOHCI::SetRootHubDescriptor(OSData * )
{
return(kIOReturnSuccess);
}
IOReturn AppleUSBOHCI::GetRootHubStatus(IOUSBHubStatus *status)
{
if ( _ohciBusState == kOHCIBusStateSuspended )
return kIOReturnNotResponding;
*(UInt32*)status = _pOHCIRegisters->hcRhStatus;
return kIOReturnSuccess;
}
IOReturn
AppleUSBOHCI::SetRootHubFeature(UInt16 wValue)
{
switch(wValue)
{
case kUSBHubLocalPowerChangeFeature :
USBLog(3,"AppleUSBOHCI[%p]::SetRootHubFeature - unimplemented Set Power Change Feature", this);
break;
case kUSBHubOverCurrentChangeFeature :
USBLog(3,"AppleUSBOHCI[%p]::SetRootHubFeature - unimplemented Set Overcurrent Change Feature", this);
break;
default:
USBLog(3,"AppleUSBOHCI[%p]::SetRootHubFeature - Unknown feature (%d)", this, wValue);
break;
}
return(kIOReturnSuccess);
}
IOReturn
AppleUSBOHCI::ClearRootHubFeature(UInt16 wValue)
{
switch(wValue)
{
case kUSBHubLocalPowerChangeFeature :
USBLog(3, "AppleUSBOHCI[%p]::ClearRootHubFeature - unimplemented Clear Power Change Feature", this);
break;
case kUSBHubOverCurrentChangeFeature :
USBLog(3, "AppleUSBOHCI[%p]::ClearRootHubFeature - unimplemented Clear Overcurrent Change Feature", this);
break;
default:
USBLog(3, "AppleUSBOHCI[%p]::ClearRootHubFeature - Unknown feature (%d)", this, wValue);
break;
}
return(kIOReturnSuccess);
}
IOReturn
AppleUSBOHCI::GetRootHubPortStatus(IOUSBHubPortStatus *status, UInt16 port)
{
if ( _ohciBusState == kOHCIBusStateSuspended )
return kIOReturnNotResponding;
if (port < 1 || port > 15)
return(kIOReturnBadArgument);
*(UInt32*)status = _pOHCIRegisters->hcRhPortStatus[port-1];
return kIOReturnSuccess;
}
IOReturn
AppleUSBOHCI::SetRootHubPortFeature(UInt16 wValue, UInt16 wIndex)
{
UInt16 port = wIndex-1;
IOReturn err = kIOReturnSuccess;
switch(wValue)
{
case kUSBHubPortSuspendFeature :
if( (_errataBits & kErrataLucentSuspendResume) && ((_disablePortsBitmap & (1 << wIndex)) != 0))
{
USBLog(3,"AppleUSBOHCI[%p]::SetRootHubPortFeature - Ignoring suspend feature", this);
err = kIOUSBPipeStalled;
}
else
OHCIRootHubPortSuspend(port, true);
break;
case kUSBHubPortResetFeature :
OHCIRootHubResetPort(port);
break;
case kUSBHubPortEnableFeature :
OHCIRootHubPortEnable(port, true);
break;
case kUSBHubPortPowerFeature :
OHCIRootHubPortPower(port, true);
OHCIRootHubPower(true);
break;
default:
USBLog(3,"AppleUSBOHCI[%p]::SetRootHubPortFeature - Unknown feature (%d)", this, wValue);
break;
}
return err;
}
IOReturn
AppleUSBOHCI::ClearRootHubPortFeature(UInt16 wValue, UInt16 wIndex)
{
UInt16 port = wIndex-1;
switch(wValue)
{
case kUSBHubPortEnableFeature :
OHCIRootHubPortEnable(port, false);
break;
case kUSBHubPortSuspendFeature :
OHCIRootHubPortSuspend(port, false);
break;
case kUSBHubPortPowerFeature :
OHCIRootHubPortPower(port, false);
break;
case kUSBHubPortConnectionChangeFeature :
OHCIRootHubResetChangeConnection(port);
break;
case kUSBHubPortEnableChangeFeature :
OHCIRootHubResetEnableChange(port);
break;
case kUSBHubPortSuspendChangeFeature :
OHCIRootHubResetSuspendChange(port);
break;
case kUSBHubPortOverCurrentChangeFeature :
OHCIRootHubResetOverCurrentChange(port);
break;
case kUSBHubPortResetChangeFeature :
OHCIRootHubResetResetChange(port);
break;
default:
USBLog(3,"AppleUSBOHCI[%p]::ClearRootHubPortFeature - Unknown feature (%d)", this, wValue);
break;
}
return(kIOReturnSuccess);
}
IOReturn
AppleUSBOHCI::GetRootHubPortState(UInt8 *, UInt16 )
{
USBLog(3,"AppleUSBOHCI[%p]::GetRootHubPortState - UNIMPLEMENTED", this);
return(kIOReturnSuccess);
}
IOReturn
AppleUSBOHCI::SetHubAddress(UInt16 wValue)
{
USBLog(3,"AppleUSBOHCI[%p]::SetHubAddress - Setting RootHub Address to %d", this, wValue);
_rootHubFuncAddress = wValue;
return (kIOReturnSuccess);
}
void
AppleUSBOHCI::OHCIRootHubPower(bool on)
{
USBLog(5,"AppleUSBOHCI[%p]::SetHubAddress - OHCIRootHubPower (%s)", this, on ? "true" : "false");
if(on)
{
_pOHCIRegisters->hcRhStatus |= HostToUSBLong(kOHCIHcRhStatus_LPSC); }
else
{
_pOHCIRegisters->hcRhStatus |= HostToUSBLong(kOHCIHcRhStatus_LPS); }
IOSync();
return;
}
void
AppleUSBOHCI::OHCIRootHubResetChangeConnection(UInt16 port)
{
UInt32 value = 0;
value |= kOHCIHcRhPortStatus_CSC;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]); while ((count++ < 10) && (newValue & kOHCIHcRhPortStatus_CSC))
{
USBError(1, "OHCI driver: OHCIRootHubResetChangeConnection bit not sticking. Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubResetResetChange(UInt16 port)
{
UInt32 value = 0;
value |= kOHCIHcRhPortStatus_PRSC;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]); while ((count++ < 10) && (newValue & kOHCIHcRhPortStatus_PRSC))
{
USBError(1, "OHCI driver: OHCIRootHubResetResetChange bit not sticking. Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubResetSuspendChange(UInt16 port)
{
UInt32 value = 0;
value |= kOHCIHcRhPortStatus_PSSC;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]); while ((count++ < 10) && (newValue & kOHCIHcRhPortStatus_PSSC))
{
USBError(1, "OHCI driver: OHCIRootHubResetSuspendChange bit not sticking. Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubResetEnableChange(UInt16 port)
{
UInt32 value = 0;
value |= kOHCIHcRhPortStatus_PESC;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]); while ((count++ < 10) && (newValue & kOHCIHcRhPortStatus_PESC))
{
USBError(1, "OHCI driver: OHCIRootHubResetEnableChange bit not sticking. Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubResetOverCurrentChange(UInt16 port)
{
UInt32 value = 0;
value |= kOHCIHcRhPortStatus_OCIC;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]); while ((count++ < 10) && (newValue & kOHCIHcRhPortStatus_OCIC))
{
USBError(1, "OHCI driver: OHCIRootHubResetOverCurrentChange bit not sticking. Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubResetPort (UInt16 port)
{
UInt32 value = 0;
value = kOHCIHcRhPortStatus_PRS; _pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(kOHCIHcRhPortStatus_PRS);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 count = 0;
value = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
while ((count++ < 10) && !(value & kOHCIHcRhPortStatus_PRS))
{
USBError(1, "OHCI driver: SetPortReset bit not sticking. Retrying.");
value = kOHCIHcRhPortStatus_PRS;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
value = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubPortEnable(UInt16 port, bool on)
{
UInt32 value = 0;
if(on)
value |= kOHCIHcRhPortStatus_PES; else
value |= kOHCIHcRhPortStatus_CCS;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
while ((count++ < 10) && (on ? !(newValue & kOHCIHcRhPortStatus_PES) : (newValue & kOHCIHcRhPortStatus_PES)))
{
USBError(1, "OHCI driver: OHCIRootHubPortEnable bit not sticking (%d). Retrying.", on);
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubPortSuspend(UInt16 port, bool on)
{
UInt32 value = 0;
if(on)
value |= kOHCIHcRhPortStatus_PSS; else
value |= kOHCIHcRhPortStatus_POCI;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if ((_errataBits & kErrataNECIncompleteWrite) && on)
{
UInt32 newValue = 0, count = 0;
IOSleep(1); newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
while ((count++ < 10) && !(newValue & kOHCIHcRhPortStatus_PSS))
{
USBError(1, "OHCI driver: OHCIRootHubPortSuspend bit not sticking (on). Retrying.");
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
IOSleep(count);
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::OHCIRootHubPortPower(UInt16 port, bool on)
{
UInt32 value = 0;
USBLog(5,"AppleUSBOHCI[%p]::OHCIRootHubPortPower for port %d", this, port);
if(on)
value |= kOHCIHcRhPortStatus_PPS; else
value |= kOHCIHcRhPortStatus_LSDA;
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
if (_errataBits & kErrataNECIncompleteWrite)
{
UInt32 newValue = 0, count = 0;
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
while ((count++ < 10) && (on ? !(newValue & kOHCIHcRhPortStatus_PPS) : (newValue & kOHCIHcRhPortStatus_PPS)))
{
USBError(1, "OHCI driver: OHCIRootHubPortPower bit not sticking (%d). Retrying.", on);
_pOHCIRegisters->hcRhPortStatus[port] = HostToUSBLong(value);
IOSync();
newValue = USBToHostLong(_pOHCIRegisters->hcRhPortStatus[port]);
}
}
return;
}
void
AppleUSBOHCI::UIMRootHubStatusChange(void)
{
UIMRootHubStatusChange(false);
}
OSMetaClassDefineReservedUsed(IOUSBController, 10);
void
AppleUSBOHCI::UIMRootHubStatusChange(bool abort)
{
UInt32 tempStatus, hubStatus, portStatus, statusBit;
UInt16 statusChangedBitmap;
UInt8 numPorts = 0;
unsigned int index, port, move;
struct InterruptTransaction last;
UInt32 descriptorA;
_pOHCIRegisters->hcInterruptDisable = HostToUSBLong(kOHCIHcInterrupt_RHSC);
IOSync();
statusChangedBitmap = 0;
statusBit = 1;
if (!abort && GetRootHubStatus((IOUSBHubStatus *)&tempStatus) == kIOReturnSuccess)
{
hubStatus = USBToHostLong( tempStatus );
if ((hubStatus & kOHCIHcRhStatus_Change ) != 0)
{
statusChangedBitmap |= statusBit;
}
descriptorA = USBToHostLong(_pOHCIRegisters->hcRhDescriptorA);
numPorts = ((descriptorA & kOHCIHcRhDescriptorA_NDP)
>> kOHCIHcRhDescriptorA_NDPPhase);
for (port = 1; port <= numPorts; port++)
{
statusBit <<= 1;
GetRootHubPortStatus((IOUSBHubPortStatus *)&tempStatus, port);
portStatus = USBToHostLong( tempStatus);
if ((portStatus & kOHCIHcRhPortStatus_Change) != 0)
{
statusChangedBitmap |= statusBit;
}
}
}
if ( (abort || (statusChangedBitmap != 0)) && (_outstandingTrans[0].completion.action != NULL) )
{
last = _outstandingTrans[0];
IOTakeLock(_intLock);
for (index = 1; index < kMaxOutstandingTrans ; index++)
{
_outstandingTrans[index-1] = _outstandingTrans[index];
if (_outstandingTrans[index].completion.action == NULL)
{
break;
}
}
clock_get_uptime( &_lastRootHubStatusChanged );
move = last.bufLen;
if (move > sizeof(statusChangedBitmap))
move = sizeof(statusChangedBitmap);
if (numPorts < 8)
move = 1;
statusChangedBitmap = HostToUSBWord(statusChangedBitmap);
last.buf->writeBytes(0,&statusChangedBitmap, move);
IOUnlock(_intLock);
Complete(last.completion, (abort ? kIOReturnAborted : kIOReturnSuccess), last.bufLen - move);
}
if ( !abort && ((_outstandingTrans[0].completion.action != NULL) || (statusChangedBitmap == 0)) )
{
_pOHCIRegisters->hcInterruptEnable = HostToUSBLong(kOHCIHcInterrupt_RHSC);
IOSync();
}
}
void AppleUSBOHCI::SimulateRootHubInt(UInt8 endpoint,
IOMemoryDescriptor * buf,
UInt32 bufLen,
IOUSBCompletion completion)
{
int index;
AbsoluteTime lastRootHubChangeTime, currentTime;
UInt64 elapsedTime = 0;
if (endpoint != 1)
{
Complete(completion, -1, bufLen);
return;
}
IOTakeLock(_intLock);
for (index = 0; index < kMaxOutstandingTrans; index++)
{
if (_outstandingTrans[index].completion.action == NULL)
{
_outstandingTrans[index].buf = buf;
_outstandingTrans[index].bufLen = bufLen;
_outstandingTrans[index].completion = completion;
IOUnlock(_intLock);
lastRootHubChangeTime = LastRootHubPortStatusChanged( false );
clock_get_uptime( ¤tTime );
SUB_ABSOLUTETIME(¤tTime, &lastRootHubChangeTime );
absolutetime_to_nanoseconds(currentTime, &elapsedTime);
elapsedTime /= 1000000;
if ( elapsedTime < kOHCIRootHubPollingInterval )
{
USBLog(5, "AppleUSBOHCI[%p]::SimulateRootHubInt Last change was %qd ms ago. IOSleep'ing for %qd ms", this, elapsedTime, kOHCIRootHubPollingInterval - elapsedTime );
IOSleep( kOHCIRootHubPollingInterval - elapsedTime );
}
UIMRootHubStatusChange();
return;
}
}
IOUnlock(_intLock);
Complete(completion, -1, bufLen);
}
IOReturn
AppleUSBOHCI::SimulateInterruptEDCreate(UInt16 maxPacketSize, short pollingRate)
{
return kIOReturnSuccess;
}
IOReturn
AppleUSBOHCI::SimulateControlEDCreate (UInt16 maxPacketSize)
{
return kIOReturnSuccess;
}
IOReturn
AppleUSBOHCI::SimulateEDDelete (short endpointNumber, short direction)
{
return SimulateEDAbort(endpointNumber, direction);
}
IOReturn
AppleUSBOHCI::SimulateEDAbort (short endpointNumber, short direction)
{
int i;
if (endpointNumber == 1)
{
if(direction != kUSBIn)
{
USBLog(3, "AppleUSBOHCI[%p]::SimulateEDAbort - Root hub wrong direction Int pipe %d", this, direction);
return(-1);
}
USBLog(5, "AppleUSBOHCI[%p]::SimulateEDAbort Root hub aborting int transactions", this);
for( i=0; i < kMaxOutstandingTrans; i++)
{
UIMRootHubStatusChange(true);
}
}
else
{
USBLog(5, "AppleUSBOHCI[%p]::SimulateEDAbort Root hub aborting control pipe", this);
UIMRootHubStatusChange(false);
}
return kIOReturnSuccess;
}
IOReturn
AppleUSBOHCI::SimulateEDClearStall (short endpointNumber, short direction)
{
return kIOReturnSuccess;
}
AbsoluteTime
AppleUSBOHCI::LastRootHubPortStatusChanged( bool resetTime )
{
if ( resetTime )
clock_get_uptime(&_lastRootHubStatusChanged);
return _lastRootHubStatusChanged;
}
bool
AppleUSBOHCI::RootHubAreAllPortsDisconnected( )
{
UInt8 numPorts = 0;
UInt32 portStatus;
OHCIGetNumberOfPorts( &numPorts );
if ( numPorts == 0 )
return false;
while ( numPorts )
{
if ( _ohciBusState == kOHCIBusStateOff )
{
return false;
}
else
{
portStatus = USBToHostLong( _pOHCIRegisters->hcRhPortStatus[--numPorts] );
if ( (portStatus & kOHCIHcRhPortStatus_CCS) != 0 )
return false;
}
}
return true;
}
void
AppleUSBOHCI::OHCIGetNumberOfPorts( UInt8 * numPorts )
{
UInt32 descriptorA;
if ( _ohciBusState == kOHCIBusStateOff )
{
*numPorts = 0;
}
else
{
descriptorA = USBToHostLong(_pOHCIRegisters->hcRhDescriptorA);
*numPorts = ( (descriptorA & kOHCIHcRhDescriptorA_NDP) >> kOHCIHcRhDescriptorA_NDPPhase );
}
}
OSMetaClassDefineReservedUsed(IOUSBController, 14);
IOReturn
AppleUSBOHCI::GetRootHubStringDescriptor(UInt8 index, OSData *desc)
{
UInt8 productName[] = {
0, kUSBStringDesc, 0x4F, 0x00, 0x48, 0x00, 0x43, 0x00, 0x49, 0x00, 0x20, 0x00, 0x52, 0x00, 0x6F, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x48, 0x00, 0x75, 0x00, 0x62, 0x00, 0x20, 0x00, 0x53, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, };
UInt8 vendorName[] = {
0, kUSBStringDesc, 0x41, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00 };
if ( index > 2 )
return kIOReturnBadArgument;
vendorName[0] = sizeof(vendorName);
productName[0] = sizeof(productName);
if ( index == 1 )
{
if (!desc)
return kIOReturnNoMemory;
if (!desc->appendBytes(&productName, productName[0]))
return kIOReturnNoMemory;
}
if ( index == 2 )
{
if (!desc)
return kIOReturnNoMemory;
if (!desc->appendBytes(&vendorName, vendorName[0]))
return kIOReturnNoMemory;
}
return kIOReturnSuccess;
}