#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/IOUSBControllerV3.h>
#include <IOKit/usb/USB.h>
#include <IOKit/usb/USBHub.h>
#include "USBOHCI.h"
#include "USBOHCIRootHub.h"
#include "AppleUSBEHCI.h"
#ifndef OHCI_USE_KPRINTF
#define OHCI_USE_KPRINTF 0
#endif
#if OHCI_USE_KPRINTF
#undef USBLog
#undef USBError
void kprintf(const char *format, ...)
__attribute__((format(printf, 1, 2)));
#define USBLog( LEVEL, FORMAT, ARGS... ) if ((LEVEL) <= OHCI_USE_KPRINTF) { kprintf( FORMAT "\n", ## ARGS ) ; }
#define USBError( LEVEL, FORMAT, ARGS... ) { kprintf( FORMAT "\n", ## ARGS ) ; }
#endif
#ifdef __ppc__
#define IOSync eieio
#else
#define IOSync() __asm__ __volatile__ ( "mfence" : : : "memory" )
#endif
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;
bool pAborting;
};
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; IOPhysicalAddress pPhysical; AppleOHCIIsochTransferDescriptorPtr pLogicalNext; OHCIIsochTransferDescriptorSharedPtr pShared; IOUSBIsocCompletion completion; IOUSBIsocFrame * pIsocFrame; UInt32 frameNum; bool requestFromRosettaClient; };
class IONaturalMemoryCursor;
class AppleUSBOHCIedMemoryBlock;
class AppleUSBOHCIitdMemoryBlock;
class AppleUSBOHCIgtdMemoryBlock;
class AppleUSBOHCI : public IOUSBControllerV3
{
OSDeclareDefaultStructors(AppleUSBOHCI)
private:
void ResumeUSBBus(bool wakingFromSleep);
void SuspendUSBBus(bool goingToSleep);
void printTD(AppleOHCIGeneralTransferDescriptorPtr pTD, int level);
void printED(AppleOHCIEndpointDescriptorPtr pED, int level);
void print_td(AppleOHCIGeneralTransferDescriptorPtr x, int level);
void print_itd(AppleOHCIIsochTransferDescriptorPtr x, int level);
void print_ed(AppleOHCIEndpointDescriptorPtr x, int level);
void print_isoc_ed(AppleOHCIEndpointDescriptorPtr x, int level, bool printSkipped, bool printTDs);
void print_list(AppleOHCIEndpointDescriptorPtr pListHead, AppleOHCIEndpointDescriptorPtr pListTail, int level, bool printSkipped, bool printTDs);
void print_control_list(int level, bool printSkipped, bool printTDs);
void print_bulk_list(int level, bool printSkipped, bool printTDs);
void print_int_list(int level, bool printSkipped, bool printTDs);
bool IsValidPhysicalAddress(IOPhysicalAddress pageAddr);
void showRegisters(UInt32 level, const char *s);
protected:
IOMemoryMap * _deviceBase;
AppleOHCIGeneralTransferDescriptorPtr _pendingHead;
AppleOHCIGeneralTransferDescriptorPtr _pendingTail;
UInt16 _vendorID;
UInt16 _deviceID;
UInt16 _revisionID;
UInt32 _errataBits; OHCIRegistersPtr _pOHCIRegisters; Ptr _pHCCA; IOBufferMemoryDescriptor * _hccaBuffer; 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; 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;
bool _uimInitialized;
bool _hasPCIPwrMgmt;
IOPhysicalAddress _hccaPhysAddr;
AbsoluteTime _lastCheckedTime; AbsoluteTime _lastRootHubStatusChanged; AbsoluteTime _filterTimeStamp;
AbsoluteTime _filterTimeStamp2;
UInt32 _lowLatencyIsochTDsProcessed; UInt32 _filterInterruptCount;
UInt32 _framesUpdated;
UInt32 _framesError;
UInt32 _resumeDetectedInterrupt; UInt32 _unrecoverableErrorInterrupt; UInt32 _rootHubStatusChangeInterrupt; UInt32 _writeDoneHeadInterrupt; UInt32 _frameNumberOverflowInterrupt; volatile IOPhysicalAddress _savedDoneQueueHead; volatile UInt32 _producerCount; volatile UInt32 _consumerCount; IOSimpleLock * _wdhLock;
UInt64 _timeElapsed;
AbsoluteTime _tempAnchorTime;
AbsoluteTime _anchorTime;
UInt64 _tempAnchorFrame;
UInt64 _anchorFrame;
UInt32 _ExpressCardPort; bool _badExpressCardAttached; bool _needToReEnableRHSCInterrupt; bool _rootHubStatuschangedInterruptReceived; UInt32 _savedHcRhPortStatus[15];
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);
IOReturn InitializeOperationalRegisters(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, bool clearToggle);
IOReturn DoDoneQueueProcessing(IOPhysicalAddress cachedWritedoneQueueHead, UInt32 cachedProducer, IOUSBCompletionAction safeAction);
void UIMProcessDoneQueue(IOUSBCompletionAction safeAction=0);
virtual void UIMRootHubStatusChange( void );
virtual void UIMRootHubStatusChange( bool abort );
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);
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 powerChangeDone ( unsigned long fromState);
virtual bool willTerminate(IOService * provider, IOOptionBits options);
virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer );
virtual void free();
IOReturn UIMInitialize(IOService * provider);
IOReturn UIMFinalize();
virtual IOReturn AllocatePowerStateArray(void);
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 UIMCreateIsochTransfer(IOUSBIsocCommand *command);
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 );
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);
virtual IODMACommand *GetNewDMACommand();
virtual IOReturn GetFrameNumberWithTime(UInt64* frameNumber, AbsoluteTime *theTime);
static IOReturn GatedGetFrameNumberWithTime(OSObject *owner, void* arg0, void* arg1, void* arg2, void* arg3);
void CheckSleepCapability(void);
virtual IOReturn ResetControllerState(void);
virtual IOReturn RestartControllerFromReset(void);
virtual IOReturn SaveControllerStateForSleep(void);
virtual IOReturn RestoreControllerStateFromSleep(void);
virtual IOReturn DozeController(void);
virtual IOReturn WakeControllerFromDoze(void);
virtual IOReturn UIMEnableAddressEndpoints(USBDeviceAddress address, bool enable);
virtual IOReturn UIMEnableAllEndpoints(bool enable);
virtual IOReturn EnableInterruptsFromController(bool enable);
};
enum
{
kUIMFlagsCallbackTD = 0x0001, kUIMFlagsMultiTDTransaction = 0x0002, kUIMFlagsFinalTDinTransaction = 0x0004 };
enum
{
kOHCICheckForRootHubConnectionsPeriod = 30, kOHCICheckForRootHubInactivityPeriod = 30 };
#endif