#ifndef _APPLEUSBIRDA_
#define _APPLEUSBIRDA_
#include <IOKit/usb/IOUSBDevice.h>
#include <IOKit/serial/IOSerialDriverSync.h>
#include "AppleIrDA.h"
#define defaultName "IrDA Device"
#define productNameLength 32 // Arbitrary length
#define propertyTag "Product Name"
#define USBIrDAClassDescriptor 0x21
enum {
kLinkSpeedIgnored = 0,
kLinkSpeed2400 = 1,
kLinkSpeed9600 = 2,
kLinkSpeed19200 = 3,
kLinkSpeed38400 = 4,
kLinkSpeed57600 = 5,
kLinkSpeed115200 = 6,
kLinkSpeed576000 = 7,
kLinkSpeed1152000 = 8,
kLinkSpeed4000000 = 9,
kLinkSpeedMask = 0x0f };
#define SPECIAL_SHIFT (5)
#define SPECIAL_MASK ((1<<SPECIAL_SHIFT) - 1)
#define STATE_ALL ( PD_RS232_S_MASK | PD_S_MASK )
#define FLOW_RX_AUTO ( PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO )
#define FLOW_TX_AUTO ( PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD )
#define CAN_BE_AUTO ( FLOW_RX_AUTO | FLOW_TX_AUTO )
#define CAN_NOTIFY ( PD_RS232_N_MASK )
#define EXTERNAL_MASK ( PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP) )
#define INTERNAL_DELAY ( PD_RS232_S_LOOP )
#define DEFAULT_AUTO ( PD_RS232_A_DTR | PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR )
#define DEFAULT_NOTIFY 0x00
#define DEFAULT_STATE ( PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO )
#define IDLE_XO 0
#define NEEDS_XOFF 1
#define SENT_XOFF -1
#define NEEDS_XON 2
#define SENT_XON -2
#define INTERRUPT_BUFF_SIZE 1
#define USBLapPayLoad 2048
typedef struct
{
UInt32 ints;
UInt32 txInts;
UInt32 rxInts;
UInt32 mdmInts;
UInt32 txChars;
UInt32 rxChars;
} Stats_t;
typedef struct BufferMarks
{
unsigned long BufferSize;
unsigned long HighWater;
unsigned long LowWater;
bool OverRun;
} BufferMarks;
typedef struct
{
UInt32 State;
UInt32 WatchStateMask;
IOLock *serialRequestLock;
CirQueue RX;
CirQueue TX;
BufferMarks RXStats;
BufferMarks TXStats;
UInt32 CharLength;
UInt32 StopBits;
UInt32 TX_Parity;
UInt32 RX_Parity;
UInt32 BaudRate;
UInt8 FCRimage;
UInt8 IERmask;
bool MinLatency;
UInt8 XONchar;
UInt8 XOFFchar;
UInt32 SWspecial[ 0x100 >> SPECIAL_SHIFT ];
UInt32 FlowControl;
int RXOstate;
int TXOstate;
IOThread FrameTOEntry;
mach_timespec DataLatInterval;
mach_timespec CharLatInterval;
bool AreTransmitting;
bool isDriver;
void *DriverPowerRegister;
UInt32 DriverPowerMask;
} PortInfo_t;
class IrDAComm;
class AppleUSBIrDADriver;
class AppleUSBIrDA : public AppleIrDASerial {
OSDeclareDefaultStructors( AppleUSBIrDA ) ;
public:
bool attach(AppleUSBIrDADriver *provider);
void Add_RXBytes( UInt8 *Buffer, size_t Size );
SInt16 SetBofCount( SInt16 bof_count );
UInt16 SetSpeed( UInt32 brate );
bool SetUpTransmit( void );
IOReturn StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer );
USBIrDAQoS* GetIrDAQoS( void );
IrDAComm* GetIrDAComm( void );
void GetIrDAStatus( IrDAStatus *status );
IOReturn SetIrDAUserClientState( bool IrDAOn );
};
class AppleUSBIrDADriver : public IOSerialDriverSync
{
OSDeclareDefaultStructors( AppleUSBIrDADriver ) ;
private:
UInt32 fCount; UInt8 fSessions; bool fUserClientStarted; bool fUSBStarted; bool fTerminate; UInt8 fProductName[productNameLength]; PortInfo_t *fPort; bool fReadActive; bool fWriteActive; UInt8 fPowerState;
IrDAComm *fIrDA; AppleUSBIrDA *fNub; AppleIrDA *fUserClientNub; USBIrDAQoS fQoS; bool fIrDAOn; bool fSuspendFail;
UInt8 fBaudCode; UInt8 fBofsCode; UInt8 fMediabusy; UInt8 fLastChangeByte; UInt32 fCurrentBaud;
IOBufferMemoryDescriptor *fpinterruptPipeMDP;
IOBufferMemoryDescriptor *fpPipeInMDP;
IOBufferMemoryDescriptor *fpPipeOutMDP;
UInt8 *fpinterruptPipeBuffer;
UInt8 *fPipeInBuffer;
UInt8 *fPipeOutBuffer;
UInt8 fpInterfaceNumber;
IOUSBCompletion finterruptCompletionInfo;
IOUSBCompletion fReadCompletionInfo;
IOUSBCompletion fWriteCompletionInfo;
IOUSBCompletion fRequestCompletionInfo;
static void interruptReadComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
static void dataReadComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
static void dataWriteComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
static void workAroundComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
bool initForPM(IOService *provider);
public:
IOUSBDevice *fpDevice;
IOUSBInterface *fpInterface;
IOUSBPipe *fpInPipe;
IOUSBPipe *fpOutPipe;
IOUSBPipe *fpInterruptPipe;
virtual bool init( OSDictionary *dict );
virtual IOService* probe( IOService *provider, SInt32 *score );
virtual bool start( IOService *provider );
virtual void free( void );
virtual void stop( IOService *provider );
virtual IOReturn message( UInt32 type, IOService *provider, void *argument = 0 );
virtual IOReturn acquirePort( bool sleep, void *refCon );
virtual IOReturn releasePort( void *refCon );
virtual IOReturn setState( UInt32 state, UInt32 mask, void *refCon );
virtual UInt32 getState( void *refCon );
virtual IOReturn watchState( UInt32 *state, UInt32 mask, void *refCon );
virtual UInt32 nextEvent( void *refCon );
virtual IOReturn executeEvent( UInt32 event, UInt32 data, void *refCon );
virtual IOReturn requestEvent( UInt32 event, UInt32 *data, void *refCon );
virtual IOReturn enqueueEvent( UInt32 event, UInt32 data, bool sleep, void *refCon );
virtual IOReturn dequeueEvent( UInt32 *event, UInt32 *data, bool sleep, void *refCon );
virtual IOReturn enqueueData( UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon );
virtual IOReturn dequeueData( UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon );
virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags );
virtual IOReturn setPowerState(unsigned long powerStateOrdinal, IOService * whatDevice);
void Add_RXBytes( UInt8 *Buffer, size_t Size );
SInt16 SetBofCount( SInt16 bof_count );
UInt16 SetSpeed( UInt32 brate );
bool SetUpTransmit( void );
IOReturn StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer );
IrDAComm* GetIrDAComm( void );
void GetIrDAStatus( IrDAStatus *status );
IOReturn SetIrDAUserClientState( bool IrDAOn );
USBIrDAQoS* GetIrDAQoS( void );
private:
QueueStatus AddBytetoQueue( CirQueue *Queue, char Value );
QueueStatus GetBytetoQueue( CirQueue *Queue, UInt8 *Value );
QueueStatus InitQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size );
QueueStatus CloseQueue( CirQueue *Queue );
size_t AddtoQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size );
size_t RemovefromQueue( CirQueue *Queue, UInt8 *Buffer, size_t MaxSize );
size_t FreeSpaceinQueue( CirQueue *Queue );
size_t UsedSpaceinQueue( CirQueue *Queue );
size_t GetQueueSize( CirQueue *Queue );
void CheckQueues( PortInfo_t *port );
IOReturn privateWatchState( PortInfo_t *port, UInt32 *state, UInt32 mask );
UInt32 readPortState( PortInfo_t *port );
void changeState( PortInfo_t *port, UInt32 state, UInt32 mask );
IOReturn CheckIrDAState();
bool configureDevice( UInt8 numConfigs );
void Workaround();
bool allocateResources( void ); void releaseResources( void ); bool startPipes(); void stopPipes();
bool createSerialStream(); void destroySerialStream(); bool createSuffix( unsigned char *sufKey );
bool startIrDA(); void stopIrDA(); bool createNub(); void destroyNub();
void SetStructureDefaults( PortInfo_t *port, bool Init );
bool allocateRingBuffer( CirQueue *Queue, size_t BufferSize );
void freeRingBuffer( CirQueue *Queue );
};
#endif