#ifndef _IOKIT_APPLEUSBHUBPORT_H
#define _IOKIT_APPLEUSBHUBPORT_H
#include <IOKit/IOLib.h>
#include <IOKit/IOService.h>
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/usb/USB.h>
#include <IOKit/usb/USBHub.h>
#include <IOKit/usb/IOUSBLog.h>
#include "AppleUSBHub.h"
#include <kern/thread_call.h>
class AppleUSBHubPort;
class AppleUSBHub;
typedef IOReturn (AppleUSBHubPort::*ChangeHandlerFuncPtr)(UInt16 changeFlags, UInt16 statusFlags);
typedef struct
{
ChangeHandlerFuncPtr handler;
UInt32 bit;
UInt32 clearFeature;
} portStatusChangeVector;
enum{
kNumChangeHandlers = 5
};
typedef enum
{
hpsNormal = 0,
hpsDead,
hpsDeviceZero,
hpsDeadDeviceZero,
hpsSetAddress,
hpsSetAddressFailed
} USBHubPortEnumState;
typedef enum
{
usbHPPMS_uninitialized = 0,
usbHPPMS_pm_suspended,
usbHPPMS_drvr_suspended,
usbHPPMS_active
} USBHubPortPMState;
struct CaptiveErrataListEntryStruct
{
UInt16 vendorID;
UInt16 productIDLo;
UInt16 productIDHi;
};
typedef struct CaptiveErrataListEntryStruct CaptiveErrataListEntry, *CaptiveErrataListEntryPtr;
class AppleUSBHubPort : public OSObject
{
friend class AppleUSBHub;
OSDeclareDefaultStructors(AppleUSBHubPort)
protected:
IOUSBDeviceDescriptor _desc;
UInt8 _speed; UInt32 _portPowerAvailable;
int _portNum;
IOUSBController * _bus;
AppleUSBHub * _hub;
IOUSBHubDescriptor * _hubDesc;
IOUSBDevice * _portDevice;
USBHubPortPMState _portPMState;
bool _devZero;
bool _captive;
bool _retryPortStatus;
bool _statusChangedThreadActive;
UInt8 _statusChangedState;
UInt8 _connectionChangedState;
bool _initThreadActive;
bool _inCommandSleep;
bool _delayOnStatusChange;
bool _addDeviceThreadActive;
bool _enablePowerAfterOvercurrentThreadActive;
UInt32 _attachRetry;
bool _attachMessageDisplayed;
bool _attachRetryFailed;
bool _overCurrentNoticeDisplayed;
AbsoluteTime _overCurrentNoticeTimeStamp;
UInt32 _portResumeRecoveryTime;
portStatusChangeVector _changeHandler[kNumChangeHandlers];
private:
thread_call_t _initThread;
thread_call_t _portStatusChangedHandlerThread;
thread_call_t _addDeviceThread;
thread_call_t _enablePowerAfterOvercurrentThread;
IOUSBHubPortStatus _portStatus;
USBHubPortEnumState _state;
IOLock * _runLock; IOLock * _initLock; IOLock * _removeDeviceLock; bool _getDeviceDescriptorFailed;
UInt8 _setAddressFailed;
UInt32 _devZeroCounter;
bool _extraResetDelay;
bool _resumePending;
bool _lowerPowerStateOnResume;
bool _usingExtraPortPower;
bool _ignoreDisconnectOnWakeup;
bool _printConnectIOLog;
bool _suspendChangeAlreadyLogged; SInt32 _debounceCount;
bool _detectedExpressCardCantWake;
UInt16 _cachedBadExpressCardVID;
UInt16 _cachedBadExpressCardPID;
static void PortInitEntry(OSObject *target); static void PortStatusChangedHandlerEntry(OSObject *target); static void AddDeviceEntry(OSObject *target); static void EnablePowerAfterOvercurrentEntry(OSObject *target);
IOReturn DetachDevice();
IOReturn GetDevZeroDescriptorWithRetries();
bool AcquireDeviceZero();
void ReleaseDeviceZero();
protected:
virtual IOReturn init(AppleUSBHub * parent, int portNum, UInt32 powerAvailable, bool captive);
virtual void PortInit(void);
virtual void PortStatusChangedHandler(void);
public:
virtual IOReturn start(void);
virtual void stop(void);
virtual void free(void);
protected:
void AddDevice(void); void RemoveDevice(void);
IOReturn ResetPort();
IOReturn ClearTT(bool multiTTs, UInt32 options);
bool StatusChanged(void);
void InitPortVectors(void);
void SetPortVector(ChangeHandlerFuncPtr routine, UInt32 condition);
IOReturn DefaultOverCrntChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn DefaultResetChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn DefaultSuspendChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn DefaultEnableChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn DefaultConnectionChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn AddDeviceResetChangeHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn HandleResetPortHandler(UInt16 changeFlags, UInt16 statusFlags);
IOReturn HandleSuspendPortHandler(UInt16 changeFlags, UInt16 statusFlags);
void FatalError(IOReturn err, const char *str);
IOReturn ReleaseDevZeroLock( void);
IOReturn SuspendPort(bool suspend, bool fromDevice);
IOReturn ReEnumeratePort(UInt32 options);
bool IsCaptiveOverride(UInt16 vendorID, UInt16 prodID);
bool ShouldApplyDisconnectWorkaround();
IOReturn LaunchAddDeviceThread();
void DisplayOverCurrentNotice(bool individual);
void EnablePowerAfterOvercurrent();
bool HasExpressCardCantWake();
AppleUSBHub * GetHub() { return _hub; }
bool IsCaptive() { return _captive; }
bool GetDevZeroLock() { return _devZero; }
UInt32 GetPortTimeStamp() { return _devZeroCounter; }
bool DetectExpressCardCantWake();
private:
IOReturn Suspend( bool fromDevice, bool portStatusSuspended );
IOReturn Resume();
void WaitForSuspendCommand( void *event, uint64_t timeout );
void WakeSuspendCommand( void *event );
void MessageDeviceClients( UInt32 type, void * argument = 0, vm_size_t argSize = 0 );
};
#endif _IOKIT_APPLEUSBHUBPORT_H