#ifndef _IOKIT_AppleUSBOHCI_H
#define _IOKIT_AppleUSBOHCI_H
#include <libkern/c++/OSData.h>
#include <IOKit/IOService.h>
#include <IOKit/IOInterruptEventSource.h>
#include <IOKit/IOFilterInterruptEventSource.h>
#include <IOKit/pci/IOPCIBridge.h>
#include <IOKit/pci/IOPCIDevice.h>
#include <IOKit/usb/IOUSBControllerV2.h>
#include <IOKit/usb/USB.h>
#include <IOKit/usb/USBHub.h>
#include "USBOHCI.h"
#include "USBOHCIRootHub.h"
#define USB_CONSTANT16(x) (OSSwapHostToLittleConstInt16(x))
#define MICROSECOND (1)
#define MILLISECOND (1000)
#ifdef __ppc__
#define IOSync eieio
#else
#define IOSync()
#endif
extern "C" {
extern void delay(int);
};
struct InterruptTransaction {
IOMemoryDescriptor * buf;
UInt32 bufLen;
IOUSBCompletion completion;
};
#define kMaxOutstandingTrans 4
typedef struct AppleOHCIIntHeadStruct
AppleOHCIIntHead,
*AppleOHCIIntHeadPtr;
typedef struct AppleOHCIEndpointDescriptorStruct
AppleOHCIEndpointDescriptor,
*AppleOHCIEndpointDescriptorPtr;
typedef struct AppleOHCIGeneralTransferDescriptorStruct
AppleOHCIGeneralTransferDescriptor,
*AppleOHCIGeneralTransferDescriptorPtr;
typedef struct AppleOHCIIsochTransferDescriptorStruct
AppleOHCIIsochTransferDescriptor,
*AppleOHCIIsochTransferDescriptorPtr;
struct AppleOHCIIntHeadStruct
{
AppleOHCIEndpointDescriptorPtr pHead;
AppleOHCIEndpointDescriptorPtr pTail;
IOPhysicalAddress pHeadPhysical;
int nodeBandwidth;
};
struct AppleOHCIEndpointDescriptorStruct
{
OHCIEndpointDescriptorSharedPtr pShared;
AppleOHCIEndpointDescriptorPtr pLogicalNext;
IOPhysicalAddress pPhysical;
void* pLogicalTailP;
void* pLogicalHeadP;
};
struct AppleOHCIGeneralTransferDescriptorStruct
{
UInt16 pType; UInt16 uimFlags; IOPhysicalAddress pPhysical; AppleOHCIGeneralTransferDescriptorPtr pLogicalNext; OHCIGeneralTransferDescriptorSharedPtr pShared; IOUSBCommand * command; UInt32 lastFrame; UInt32 lastRemaining; AppleOHCIEndpointDescriptorPtr pEndpoint; UInt32 bufferSize; };
struct AppleOHCIIsochTransferDescriptorStruct
{
UInt16 pType; UInt16 uimFlags; UInt32 pPhysical; AppleOHCIIsochTransferDescriptorPtr pLogicalNext; OHCIIsochTransferDescriptorSharedPtr pShared; IOUSBIsocCompletion completion; IOUSBIsocFrame * pIsocFrame; UInt32 frameNum; bool requestFromRosettaClient; };
class IONaturalMemoryCursor;
class AppleUSBOHCIedMemoryBlock;
class AppleUSBOHCIitdMemoryBlock;
class AppleUSBOHCIgtdMemoryBlock;
class AppleUSBOHCI : public IOUSBControllerV2
{
OSDeclareDefaultStructors(AppleUSBOHCI)
private:
virtual IOReturn setPowerState( unsigned long, IOService* );
virtual void initForPM (IOPCIDevice *provider);
unsigned long maxCapabilityForDomainState ( IOPMPowerFlags domainState );
unsigned long initialPowerStateForDomainState ( IOPMPowerFlags domainState );
void ResumeUSBBus();
void SuspendUSBBus();
void print_td(AppleOHCIGeneralTransferDescriptorPtr x);
void print_itd(AppleOHCIIsochTransferDescriptorPtr x);
void print_ed(AppleOHCIEndpointDescriptorPtr x);
void print_isoc_ed(AppleOHCIEndpointDescriptorPtr x);
void print_list(AppleOHCIEndpointDescriptorPtr pListHead, AppleOHCIEndpointDescriptorPtr pListTail);
void print_control_list(void);
void print_bulk_list(void);
void print_int_list(void);
bool IsValidPhysicalAddress(IOPhysicalAddress pageAddr);
protected:
IOPCIDevice * _device;
IOMemoryMap * _deviceBase;
IONaturalMemoryCursor * _genCursor;
IONaturalMemoryCursor * _isoCursor;
AppleOHCIGeneralTransferDescriptorPtr _pendingHead;
AppleOHCIGeneralTransferDescriptorPtr _pendingTail;
UInt16 _vendorID;
UInt16 _deviceID;
UInt16 _revisionID;
UInt32 _errataBits; OHCIRegistersPtr _pOHCIRegisters; Ptr _pHCCA; AppleOHCIIntHead _pInterruptHead[63]; volatile AppleOHCIEndpointDescriptorPtr _pIsochHead; volatile AppleOHCIEndpointDescriptorPtr _pIsochTail; volatile AppleOHCIEndpointDescriptorPtr _pBulkHead; volatile AppleOHCIEndpointDescriptorPtr _pControlHead; volatile AppleOHCIEndpointDescriptorPtr _pBulkTail; volatile AppleOHCIEndpointDescriptorPtr _pControlTail; volatile AppleOHCIGeneralTransferDescriptorPtr _pFreeTD; volatile AppleOHCIIsochTransferDescriptorPtr _pFreeITD; volatile AppleOHCIEndpointDescriptorPtr _pFreeED; volatile AppleOHCIGeneralTransferDescriptorPtr _pLastFreeTD; volatile AppleOHCIIsochTransferDescriptorPtr _pLastFreeITD; volatile AppleOHCIEndpointDescriptorPtr _pLastFreeED; volatile AppleOHCIGeneralTransferDescriptorPtr _pPendingTD; AppleUSBOHCIedMemoryBlock* _edMBHead; AppleUSBOHCIgtdMemoryBlock* _gtdMBHead; AppleUSBOHCIitdMemoryBlock* _itdMBHead; UInt32 _pageSize; struct {
volatile UInt32 scheduleOverrun; volatile UInt32 unrecoverableError; volatile UInt32 frameNumberOverflow; volatile UInt32 ownershipChange; } _errors;
volatile UInt64 _frameNumber;
UInt16 _rootHubFuncAddress; int _OptiOn;
UInt32 _isochBandwidthAvail; UInt32 _disablePortsBitmap; UInt32 _dataAllocationSize; IOFilterInterruptEventSource * _filterInterruptSource;
IOLock * _intLock;
struct InterruptTransaction _outstandingTrans[kMaxOutstandingTrans];
bool _uimInitialized;
bool _unloadUIMAcrossSleep;
bool _onCardBus;
bool _idleSuspend;
bool _hasPCIPwrMgmt;
bool _ohciAvailable;
IOPhysicalAddress _hccaPhysAddr;
UInt8 _ohciBusState;
AbsoluteTime _lastCheckedTime; AbsoluteTime _lastRootHubStatusChanged; AbsoluteTime _filterTimeStamp;
AbsoluteTime _filterTimeStamp2;
UInt32 _lowLatencyIsochTDsProcessed; UInt32 _filterInterruptCount;
UInt32 _framesUpdated;
UInt32 _framesError;
UInt32 _resumeDetectedInterrupt; UInt32 _unrecoverableErrorInterrupt; UInt32 _rootHubStatusChangeInterrupt; UInt32 _writeDoneHeadInterrupt; volatile IOPhysicalAddress _savedDoneQueueHead; volatile UInt32 _producerCount; volatile UInt32 _consumerCount; IOSimpleLock * _wdhLock;
UInt64 _timeElapsed;
bool _needToCreateRootHub;
static void InterruptHandler(OSObject *owner, IOInterruptEventSource * source, int count);
static bool PrimaryInterruptFilter(OSObject *owner, IOFilterInterruptEventSource *source);
bool FilterInterrupt(int index);
void SetVendorInfo(void);
void finishPending();
IOReturn ControlInitialize(void);
IOReturn BulkInitialize (void);
IOReturn IsochronousInitialize(void);
IOReturn InterruptInitialize (void);
const OSSymbol * _usb_remote_wakeup;
bool _remote_wakeup_occurred;
void doCallback(AppleOHCIGeneralTransferDescriptorPtr nextTD, UInt32 transferStatus, UInt32 bufferSizeRemaining);
UInt32 findBufferRemaining (AppleOHCIGeneralTransferDescriptorPtr pCurrentTD);
AppleOHCIIsochTransferDescriptorPtr AllocateITD(void);
AppleOHCIGeneralTransferDescriptorPtr AllocateTD(void);
AppleOHCIEndpointDescriptorPtr AllocateED(void);
IOReturn TranslateStatusToUSBError(UInt32 status);
void ProcessCompletedITD (AppleOHCIIsochTransferDescriptorPtr pITD, IOReturn status);
IOReturn DeallocateITD (AppleOHCIIsochTransferDescriptorPtr pTD);
IOReturn DeallocateTD (AppleOHCIGeneralTransferDescriptorPtr pTD);
IOReturn DeallocateED (AppleOHCIEndpointDescriptorPtr pED);
IOReturn RemoveAllTDs(AppleOHCIEndpointDescriptorPtr pED);
IOReturn RemoveTDs(AppleOHCIEndpointDescriptorPtr pED);
IOReturn DoDoneQueueProcessing(IOPhysicalAddress cachedWritedoneQueueHead, UInt32 cachedProducer, IOUSBCompletionAction safeAction);
void UIMProcessDoneQueue(IOUSBCompletionAction safeAction=0);
void UIMRootHubStatusChange( void );
void UIMRootHubStatusChange(bool abort);
void SimulateRootHubInt(
UInt8 endpoint,
IOMemoryDescriptor * buf,
UInt32 bufLen,
IOUSBCompletion completion);
IOReturn SimulateInterruptEDCreate(UInt16 maxPacketSize, short pollingRate);
IOReturn SimulateControlEDCreate (UInt16 maxPacketSize);
IOReturn SimulateEDAbort (short endpointNumber, short direction);
IOReturn SimulateEDDelete (short endpointNumber, short direction);
IOReturn SimulateEDClearStall (short endpointNumber, short direction);
AppleOHCIEndpointDescriptorPtr AddEmptyEndPoint(
UInt8 functionAddress,
UInt8 endpointNumber,
UInt16 maxPacketSize,
UInt8 speed,
UInt8 direction,
AppleOHCIEndpointDescriptorPtr pED,
OHCIEDFormat format);
AppleOHCIEndpointDescriptorPtr FindEndpoint (
short functionNumber,
short endpointNumber,
short direction,
AppleOHCIEndpointDescriptorPtr *pEDQueueBack,
UInt32 *controlMask);
AppleOHCIEndpointDescriptorPtr FindControlEndpoint (
short functionNumber,
short endpointNumber,
AppleOHCIEndpointDescriptorPtr *pEDBack);
AppleOHCIEndpointDescriptorPtr FindBulkEndpoint (
short functionNumber,
short endpointNumber,
short direction,
AppleOHCIEndpointDescriptorPtr *pEDBack);
AppleOHCIEndpointDescriptorPtr FindIsochronousEndpoint(
short functionNumber,
short endpointNumber,
short direction,
AppleOHCIEndpointDescriptorPtr *pEDBack);
AppleOHCIEndpointDescriptorPtr FindInterruptEndpoint(
short functionNumber,
short endpointNumber,
short direction,
AppleOHCIEndpointDescriptorPtr *pEDBack);
void DoOptiFix(AppleOHCIEndpointDescriptorPtr pIsochHead);
void OptiLSHSFix(void);
void dumpRegs(void);
bool DetermineInterruptOffset(UInt32 pollingRate,
UInt32 reserveBandwidth,
int *offset);
void ReturnTransactions(
AppleOHCIGeneralTransferDescriptorPtr transaction,
UInt32 tail);
void ReturnOneTransaction(
AppleOHCIGeneralTransferDescriptorPtr transaction,
AppleOHCIEndpointDescriptorPtr pED,
IOReturn err);
void CheckEDListForTimeouts(
AppleOHCIEndpointDescriptorPtr head,
AppleOHCIEndpointDescriptorPtr tail);
void ReturnAllTransactionsInEndpoint(
AppleOHCIEndpointDescriptorPtr head,
AppleOHCIEndpointDescriptorPtr tail);
public:
virtual bool init(OSDictionary * propTable);
virtual bool start( IOService * provider );
virtual void stop( IOService * provider );
virtual bool finalize(IOOptionBits options);
virtual IOReturn message( UInt32 type, IOService * provider, void * argument = 0 );
virtual void free();
IOReturn UIMInitialize(IOService * provider);
IOReturn UIMFinalize();
IOReturn UIMInitializeForPowerUp();
IOReturn UIMFinalizeForPowerDown();
virtual IOReturn UIMCreateControlEndpoint(
UInt8 functionNumber,
UInt8 endpointNumber,
UInt16 maxPacketSize,
UInt8 speed);
virtual IOReturn UIMCreateControlEndpoint(
UInt8 functionNumber,
UInt8 endpointNumber,
UInt16 maxPacketSize,
UInt8 speed,
USBDeviceAddress highSpeedHub,
int highSpeedPort);
virtual IOReturn UIMCreateControlTransfer(
short functionNumber,
short endpointNumber,
IOUSBCompletion completion,
void * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateControlTransfer(
short functionNumber,
short endpointNumber,
IOUSBCommand* command,
void * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateControlTransfer(
short functionNumber,
short endpointNumber,
IOUSBCompletion completion,
IOMemoryDescriptor * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateControlTransfer(
short functionNumber,
short endpointNumber,
IOUSBCommand* command,
IOMemoryDescriptor * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateBulkEndpoint(
UInt8 functionNumber,
UInt8 endpointNumber,
UInt8 direction,
UInt8 speed,
UInt8 maxPacketSize);
virtual IOReturn UIMCreateBulkEndpoint(
UInt8 functionNumber,
UInt8 endpointNumber,
UInt8 direction,
UInt8 speed,
UInt16 maxPacketSize,
USBDeviceAddress highSpeedHub,
int highSpeedPort);
virtual IOReturn UIMCreateBulkTransfer(
short functionNumber,
short endpointNumber,
IOUSBCompletion completion,
IOMemoryDescriptor * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateBulkTransfer(IOUSBCommand* command);
virtual IOReturn CreateGeneralTransfer(
AppleOHCIEndpointDescriptorPtr queue,
IOUSBCommand* command,
IOMemoryDescriptor* CBP,
UInt32 bufferSize,
UInt32 flags,
UInt32 type,
UInt32 kickBits);
virtual IOReturn UIMCreateInterruptEndpoint(
short functionAddress,
short endpointNumber,
UInt8 direction,
short speed,
UInt16 maxPacketSize,
short pollingRate);
virtual IOReturn UIMCreateInterruptEndpoint(
short functionAddress,
short endpointNumber,
UInt8 direction,
short speed,
UInt16 maxPacketSize,
short pollingRate,
USBDeviceAddress highSpeedHub,
int highSpeedPort);
virtual IOReturn UIMCreateInterruptTransfer(
short functionNumber,
short endpointNumber,
IOUSBCompletion completion,
IOMemoryDescriptor * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateInterruptTransfer(IOUSBCommand* command);
virtual IOReturn UIMCreateIsochEndpoint(
short functionAddress,
short endpointNumber,
UInt32 maxPacketSize,
UInt8 direction);
virtual IOReturn UIMCreateIsochEndpoint(
short functionAddress,
short endpointNumber,
UInt32 maxPacketSize,
UInt8 direction,
USBDeviceAddress highSpeedHub,
int highSpeedPort);
virtual IOReturn UIMCreateIsochTransfer(
short functionAddress,
short endpointNumber,
IOUSBIsocCompletion completion,
UInt8 direction,
UInt64 frameStart,
IOMemoryDescriptor * pBuffer,
UInt32 frameCount,
IOUSBIsocFrame *pFrames);
virtual IOReturn UIMCreateIsochTransfer(
short functionAddress,
short endpointNumber,
IOUSBIsocCompletion completion,
UInt8 direction,
UInt64 frameStart,
IOMemoryDescriptor * pBuffer,
UInt32 frameCount,
IOUSBLowLatencyIsocFrame *pFrames,
UInt32 updateFrequency);
virtual IOReturn UIMAbortEndpoint(
short functionNumber,
short endpointNumber,
short direction);
virtual IOReturn UIMDeleteEndpoint(
short functionNumber,
short endpointNumber,
short direction);
virtual IOReturn UIMClearEndpointStall(
short functionNumber,
short endpointNumber,
short direction);
IOReturn GetRootHubDeviceDescriptor(IOUSBDeviceDescriptor *desc);
IOReturn GetRootHubDescriptor(IOUSBHubDescriptor *desc);
IOReturn SetRootHubDescriptor(OSData *buffer);
IOReturn GetRootHubConfDescriptor(OSData *desc);
IOReturn GetRootHubStatus(IOUSBHubStatus *status);
IOReturn GetRootHubStringDescriptor(UInt8 index, OSData *desc);
IOReturn SetRootHubFeature(UInt16 wValue);
IOReturn ClearRootHubFeature(UInt16 wValue);
IOReturn GetRootHubPortStatus(IOUSBHubPortStatus *status, UInt16 port);
IOReturn SetRootHubPortFeature(UInt16 wValue, UInt16 port);
IOReturn ClearRootHubPortFeature(UInt16 wValue, UInt16 port);
IOReturn GetRootHubPortState(UInt8 *state, UInt16 port);
IOReturn SetHubAddress(UInt16 wValue);
AbsoluteTime LastRootHubPortStatusChanged( bool reset );
bool RootHubAreAllPortsDisconnected( void );
void OHCIGetNumberOfPorts(UInt8 *numPorts);
void OHCIRootHubPower(bool on);
void OHCIRootHubResetChangeConnection(UInt16 port);
void OHCIRootHubResetResetChange(UInt16 port);
void OHCIRootHubResetSuspendChange(UInt16 port);
void OHCIRootHubResetEnableChange(UInt16 port);
void OHCIRootHubResetOverCurrentChange(UInt16 port);
void OHCIRootHubResetPort (UInt16 port);
void OHCIRootHubPortEnable(UInt16 port, bool on);
void OHCIRootHubPortSuspend(UInt16 port, bool on);
void OHCIRootHubPortPower(UInt16 port, bool on);
virtual UInt32 GetBandwidthAvailable();
virtual UInt64 GetFrameNumber();
virtual UInt32 GetFrameNumber32();
virtual void PollInterrupts(IOUSBCompletionAction safeAction=0);
virtual IOReturn callPlatformFunction(const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4);
virtual void UIMCheckForTimeouts(void);
};
enum
{
kUIMFlagsCallbackTD = 0x0001, kUIMFlagsMultiTDTransaction = 0x0002, kUIMFlagsFinalTDinTransaction = 0x0004 };
enum
{
kOHCIBusStateOff = 0,
kOHCIBusStateSuspended = 1,
kOHCIBusStateRunning = 2
};
enum
{
kOHCISetPowerLevelSuspend = 0,
kOHCISetPowerLevelRunning = 1,
kOHCISetPowerLevelIdleSuspend = 2
};
enum
{
kOHCICheckForRootHubConnectionsPeriod = 30, kOHCICheckForRootHubInactivityPeriod = 30 };
#endif