#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/IOUSBController.h>
#include <IOKit/usb/USB.h>
#include <IOKit/usb/USBHub.h>
#include "USBOHCI.h"
#include "USBOHCIRootHub.h"
#define USB_CONSTANT16(x) ((((x) >> 8) & 0x0ff) | ((x & 0xff) << 8))
#define MICROSECOND (1)
#define MILLISECOND (1000)
#ifdef __ppc__
#define IOSync eieio
#else
#define IOSync()
#endif
extern "C" {
extern int kvtophys(vm_offset_t);
extern void delay(int);
};
struct InterruptTransaction {
IOMemoryDescriptor * buf;
UInt32 bufLen;
IOUSBCompletion completion;
};
#define kMaxOutstandingTrans 4
class IONaturalMemoryCursor;
class AppleUSBOHCI : public IOUSBController
{
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();
virtual bool hasPCIPwrMgmt(IOOptionBits state = 0);
virtual IOReturn enablePCIPwrMgmt(IOOptionBits state = 0xffffffff);
virtual IOReturn saveDeviceState( IOPCIDevice * device,
IOOptionBits options = 0 );
virtual IOReturn restoreDeviceState( IOPCIDevice * device,
IOOptionBits options = 0 );
bool PMsleepEnabled; UInt8 PMcontrolStatus; UInt16 sleepControlBits; UInt32 *savedConfig;
void print_td(OHCIGeneralTransferDescriptorPtr x);
void print_itd(OHCIIsochTransferDescriptorPtr x);
void print_ed(OHCIEndpointDescriptorPtr x);
void print_isoc_ed(OHCIEndpointDescriptorPtr x);
void print_list(OHCIEndpointDescriptorPtr pListHead,
OHCIEndpointDescriptorPtr pListTail);
void print_control_list(void);
void print_bulk_list(void);
void print_int_list(void);
protected:
IOPCIDevice * _device;
IOMemoryMap * _deviceBase;
IONaturalMemoryCursor * _genCursor;
IONaturalMemoryCursor * _isoCursor;
OHCIGeneralTransferDescriptorPtr _pendingHead;
OHCIGeneralTransferDescriptorPtr _pendingTail;
UInt16 _vendorID;
UInt16 _deviceID;
UInt16 _revisionID;
UInt32 _errataBits; OHCIRegistersPtr _pOHCIRegisters; Ptr _pHCCA; OHCIIntHead _pInterruptHead[63]; volatile OHCIEndpointDescriptorPtr _pIsochHead; volatile OHCIEndpointDescriptorPtr _pIsochTail; volatile OHCIEndpointDescriptorPtr _pBulkHead; volatile OHCIEndpointDescriptorPtr _pControlHead; volatile OHCIEndpointDescriptorPtr _pBulkTail; volatile OHCIEndpointDescriptorPtr _pControlTail; volatile OHCIPhysicalLogicalPtr _pPhysicalLogical; volatile OHCIGeneralTransferDescriptorPtr _pFreeTD; volatile OHCIIsochTransferDescriptorPtr _pFreeITD; volatile OHCIEndpointDescriptorPtr _pFreeED; volatile OHCIGeneralTransferDescriptorPtr _pLastFreeTD; volatile OHCIIsochTransferDescriptorPtr _pLastFreeITD; volatile OHCIEndpointDescriptorPtr _pLastFreeED; volatile OHCIGeneralTransferDescriptorPtr _pPendingTD; Ptr _pDataAllocation; Ptr _pPCIAssignedAddresses; 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;
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;
UInt32 GetLogicalAddress(UInt32 pPhysicalAddress);
UInt32 GetPhysicalAddress(UInt32 LogicalAddress,
UInt32 count);
UInt32 CreatePhysicalAddress(UInt32 pLogicalAddress,
UInt32 count);
IOReturn AllocateMemory(int num_of_TDs,
int num_of_EDs,
int num_of_ITDs);
void doCallback(OHCIGeneralTransferDescriptorPtr nextTD,
UInt32 transferStatus,
UInt32 bufferSizeRemaining);
UInt32 findBufferRemaining (OHCIGeneralTransferDescriptorPtr pCurrentTD);
OHCIIsochTransferDescriptorPtr AllocateITD(void);
OHCIGeneralTransferDescriptorPtr AllocateTD(void);
OHCIEndpointDescriptorPtr AllocateED(void);
IOReturn TranslateStatusToUSBError(UInt32 status);
void ProcessCompletedITD (OHCIIsochTransferDescriptorPtr pITD, IOReturn status);
IOReturn DeallocateITD (OHCIIsochTransferDescriptorPtr pTD);
IOReturn DeallocateTD (OHCIGeneralTransferDescriptorPtr pTD);
IOReturn DeallocateED (OHCIEndpointDescriptorPtr pED);
IOReturn RemoveAllTDs(OHCIEndpointDescriptorPtr pED);
IOReturn RemoveTDs(OHCIEndpointDescriptorPtr 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);
OHCIEndpointDescriptorPtr AddEmptyEndPoint(
UInt8 functionAddress,
UInt8 endpointNumber,
UInt16 maxPacketSize,
UInt8 speed,
UInt8 direction,
OHCIEndpointDescriptorPtr pED,
OHCIEDFormat format);
OHCIEndpointDescriptorPtr FindEndpoint (
short functionNumber,
short endpointNumber,
short direction,
OHCIEndpointDescriptorPtr *pEDQueueBack,
UInt32 *controlMask);
OHCIEndpointDescriptorPtr FindControlEndpoint (
short functionNumber,
short endpointNumber,
OHCIEndpointDescriptorPtr *pEDBack);
OHCIEndpointDescriptorPtr FindBulkEndpoint (
short functionNumber,
short endpointNumber,
short direction,
OHCIEndpointDescriptorPtr *pEDBack);
OHCIEndpointDescriptorPtr FindIsochronousEndpoint(
short functionNumber,
short endpointNumber,
short direction,
OHCIEndpointDescriptorPtr *pEDBack);
OHCIEndpointDescriptorPtr FindInterruptEndpoint(
short functionNumber,
short endpointNumber,
short direction,
OHCIEndpointDescriptorPtr *pEDBack);
void DoOptiFix(OHCIEndpointDescriptorPtr pIsochHead);
void OptiLSHSFix(void);
void dumpRegs(void);
bool DetermineInterruptOffset(UInt32 pollingRate,
UInt32 reserveBandwidth,
int *offset);
void ReturnTransactions(
OHCIGeneralTransferDescriptor *transaction,
UInt32 tail);
void ReturnOneTransaction(
OHCIGeneralTransferDescriptor *transaction,
OHCIEndpointDescriptorPtr pED,
IOReturn err);
void CheckEDListForTimeouts(
OHCIEndpointDescriptorPtr head,
OHCIEndpointDescriptorPtr 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 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 UIMCreateBulkTransfer(
short functionNumber,
short endpointNumber,
IOUSBCompletion completion,
IOMemoryDescriptor * CBP,
bool bufferRounding,
UInt32 bufferSize,
short direction);
virtual IOReturn UIMCreateBulkTransfer(IOUSBCommand* command);
virtual IOReturn CreateGeneralTransfer(
OHCIEndpointDescriptorPtr 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 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 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
{
kUIMFlagsLastTD = 0x0001
};
enum
{
kOHCIBusStateOff = 0,
kOHCIBusStateSuspended = 1,
kOHCIBusStateRunning = 2
};
enum
{
kOHCISetPowerLevelSuspend = 0,
kOHCISetPowerLevelRunning = 1,
kOHCISetPowerLevelIdleSuspend = 2
};
enum
{
kOHCICheckForRootHubConnectionsPeriod = 30, kOHCICheckForRootHubInactivityPeriod = 30 };
enum
{
kPCIPMCPMESupportFromD3Cold = 0x8000,
kPCIPMCPMESupportFromD3Hot = 0x4000,
kPCIPMCPMESupportFromD2 = 0x2000,
kPCIPMCPMESupportFromD1 = 0x1000,
kPCIPMCPMESupportFromD0 = 0x0800,
kPCIPMCD2Support = 0x0400,
kPCIPMCD1Support = 0x0200
};
enum
{
kPCIPMCSPMEStatus = 0x8000,
kPCIPMCSPMEEnable = 0x0100,
kPCIPMCSPowerStateMask = 0x0003,
kPCIPMCSPowerStateD3 = 0x0003,
kPCIPMCSPowerStateD2 = 0x0002,
kPCIPMCSPowerStateD1 = 0x0001,
kPCIPMCSPowerStateD0 = 0x0000
};
#endif