1
2    /* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3     *
4     * @APPLE_LICENSE_HEADER_START@
5     *
6     * The contents of this file constitute Original Code as defined in and
7     * are subject to the Apple Public Source License Version 1.1 (the
8     * "License").  You may not use this file except in compliance with the
9     * License.  Please obtain a copy of the License at
10     * http://www.apple.com/publicsource and read it before using this file.
11     *
12     * This Original Code and all software distributed under the License are
13     * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14     * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15     * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16     * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17     * License for the specific language governing rights and limitations
18     * under the License.
19     *
20     * @APPLE_LICENSE_HEADER_END@
21     */
22
23#ifndef _APPLEUSBIRDA_
24#define _APPLEUSBIRDA_
25
26#include <IOKit/usb/IOUSBDevice.h>
27#include <IOKit/serial/IOSerialDriverSync.h>
28
29#include "AppleIrDA.h"
30
31#define defaultName     "IrDA Device"
32#define productNameLength   32                  // Arbitrary length
33#define propertyTag     "Product Name"
34
35
36    /* IrDA USB stuff */
37
38#define USBIrDAClassDescriptor  0x21
39
40enum                            // usb-irda bridge baud codes, in both rcv and xmit headers
41{
42    kLinkSpeedIgnored   = 0,
43    kLinkSpeed2400  = 1,
44    kLinkSpeed9600  = 2,
45    kLinkSpeed19200 = 3,
46    kLinkSpeed38400 = 4,
47    kLinkSpeed57600 = 5,
48    kLinkSpeed115200    = 6,
49    kLinkSpeed576000    = 7,
50    kLinkSpeed1152000   = 8,
51    kLinkSpeed4000000   = 9,
52
53    kLinkSpeedMask  = 0x0f  // low four bits in the inbound/outbound headers
54};
55
56    /* PPCSerialPort.h  */
57
58#define SPECIAL_SHIFT       (5)
59#define SPECIAL_MASK        ((1<<SPECIAL_SHIFT) - 1)
60#define STATE_ALL           ( PD_RS232_S_MASK | PD_S_MASK )
61#define FLOW_RX_AUTO        ( PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO )
62#define FLOW_TX_AUTO        ( PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD )
63#define CAN_BE_AUTO         ( FLOW_RX_AUTO | FLOW_TX_AUTO )
64#define CAN_NOTIFY          ( PD_RS232_N_MASK )
65#define EXTERNAL_MASK       ( PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP) )
66#define INTERNAL_DELAY      ( PD_RS232_S_LOOP )
67#define DEFAULT_AUTO        ( PD_RS232_A_DTR | PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR )
68#define DEFAULT_NOTIFY      0x00
69#define DEFAULT_STATE       ( PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO )
70
71#define IDLE_XO          0
72#define NEEDS_XOFF       1
73#define SENT_XOFF       -1
74#define NEEDS_XON        2
75#define SENT_XON        -2
76
77#define INTERRUPT_BUFF_SIZE 1
78#define USBLapPayLoad       2048
79
80typedef struct
81{
82    UInt32  ints;
83    UInt32  txInts;
84    UInt32  rxInts;
85    UInt32  mdmInts;
86    UInt32  txChars;
87    UInt32  rxChars;
88} Stats_t;
89
90typedef struct BufferMarks
91{
92    unsigned long   BufferSize;
93    unsigned long   HighWater;
94    unsigned long   LowWater;
95    bool            OverRun;
96} BufferMarks;
97
98typedef struct
99{
100    UInt32          State;
101    UInt32          WatchStateMask;
102    IOLock          *serialRequestLock;
103
104	// queue control structures:
105
106    CirQueue        RX;
107    CirQueue        TX;
108
109    BufferMarks     RXStats;
110    BufferMarks     TXStats;
111
112	// UART configuration info:
113
114    UInt32          CharLength;
115    UInt32          StopBits;
116    UInt32          TX_Parity;
117    UInt32          RX_Parity;
118    UInt32          BaudRate;
119    UInt8           FCRimage;
120    UInt8           IERmask;
121    bool            MinLatency;
122
123	// flow control state & configuration:
124
125    UInt8           XONchar;
126    UInt8           XOFFchar;
127    UInt32          SWspecial[ 0x100 >> SPECIAL_SHIFT ];
128    UInt32          FlowControl;    // notify-on-delta & auto_control
129
130    int             RXOstate;    /* Indicates our receive state.    */
131    int             TXOstate;    /* Indicates our transmit state, if we have received any Flow Control. */
132
133    IOThread        FrameTOEntry;
134
135    mach_timespec   DataLatInterval;
136    mach_timespec   CharLatInterval;
137
138    bool            AreTransmitting;
139
140	/* extensions to handle the Driver */
141
142    bool            isDriver;
143    void            *DriverPowerRegister;
144    UInt32          DriverPowerMask;
145
146
147} PortInfo_t;
148
149class IrDAComm;
150class AppleUSBIrDADriver;
151
152    /* AppleUSBIrDA.h - This file contains definitions for IrDA */
153class AppleUSBIrDA : public AppleIrDASerial         // glue for IrDA to call the USB IrDA Driver
154{
155    OSDeclareDefaultStructors( AppleUSBIrDA )   ;   /* Constructor & Destructor stuff   */
156public:
157    bool        attach(AppleUSBIrDADriver *provider);   // IOSerialStream attach requires a IOSerialDriverSync
158
159    void        Add_RXBytes( UInt8 *Buffer, size_t Size );
160    SInt16      SetBofCount( SInt16 bof_count );
161    UInt16      SetSpeed( UInt32 brate );
162    bool        SetUpTransmit( void );
163
164    IOReturn    StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer );
165    USBIrDAQoS* GetIrDAQoS( void );
166    IrDAComm*   GetIrDAComm( void );
167    void        GetIrDAStatus( IrDAStatus *status );
168    IOReturn    SetIrDAUserClientState( bool IrDAOn );
169};
170
171class AppleUSBIrDADriver : public IOSerialDriverSync
172{
173    OSDeclareDefaultStructors( AppleUSBIrDADriver ) ;   /* Constructor & Destructor stuff   */
174
175private:
176    UInt32          fCount;         // usb write length
177    UInt8           fSessions;      // Active sessions (count of opens on /dev/tty entries)
178    bool            fUserClientStarted; // user/client has started (stopped) us
179    bool            fUSBStarted;        // usb family has started (stopped) us
180    bool            fTerminate;     // Are we being terminated (ie the device was unplugged)
181    UInt8           fProductName[productNameLength];    // Actually the product String from the Device
182    PortInfo_t      *fPort;         // The Port
183    bool            fReadActive;    // usb read is active
184    bool            fWriteActive;   // usb write is active
185    UInt8           fPowerState;    // off,on ordinal for power management
186
187
188	// Some of these globals would normally be by port but as we only have one port it doesn't really matter
189
190    IrDAComm        *fIrDA;             // IrDA (IrCOMM) object
191    AppleUSBIrDA    *fNub;              // glue back to IOSerialStream side
192    AppleIrDA       *fUserClientNub;    // nub to publish newUserClient for us
193    USBIrDAQoS      fQoS;               // Quality of Service
194    bool            fIrDAOn;            // IrDA state (on or off)
195    bool            fSuspendFail;       // Suspend not supported or failed
196
197    UInt8           fBaudCode;          //  encoded baud code for change speed byte
198    UInt8           fBofsCode;          //  extra bof count (encoded but unshifted)
199    UInt8           fMediabusy;         //  media busy flag (0 or 1)
200    UInt8           fLastChangeByte;    //  saved BOF / baud code byte (send only if changed)
201    UInt32          fCurrentBaud;       //  current speed in bps
202
203    IOBufferMemoryDescriptor    *fpinterruptPipeMDP;
204    IOBufferMemoryDescriptor    *fpPipeInMDP;
205    IOBufferMemoryDescriptor    *fpPipeOutMDP;
206
207    UInt8               *fpinterruptPipeBuffer;
208    UInt8               *fPipeInBuffer;
209    UInt8               *fPipeOutBuffer;
210
211    UInt8               fpInterfaceNumber;
212
213    IOUSBCompletion     finterruptCompletionInfo;
214    IOUSBCompletion     fReadCompletionInfo;
215    IOUSBCompletion     fWriteCompletionInfo;
216    IOUSBCompletion     fRequestCompletionInfo;
217
218    thread_call_t	fPowerThreadCall;
219    IOCommandGate	*fGate;
220    bool		fWaitForGatedCmd;
221
222    static void         interruptReadComplete(  void *obj, void *param, IOReturn ior, UInt32 remaining );
223    static void         dataReadComplete(  void *obj, void *param, IOReturn ior, UInt32 remaining );
224    static void         dataWriteComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
225    static void         workAroundComplete( void *obj, void *param, IOReturn ior, UInt32 remaining );
226
227    bool                initForPM(IOService *provider);
228    static void		handleSetPowerState(thread_call_param_t param0, thread_call_param_t param1 );
229    static IOReturn	setPowerStateGated(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3);
230    IOReturn		setPowerStateGatedPrivate(uintptr_t powerStateOrdinal);
231
232public:
233
234    IOUSBDevice         *fpDevice;
235    IOUSBInterface      *fpInterface;
236    IOUSBPipe           *fpInPipe;
237    IOUSBPipe           *fpOutPipe;
238    IOUSBPipe           *fpInterruptPipe;
239
240	/* IOKit methods:   */
241
242    virtual bool        init( OSDictionary *dict );
243    virtual IOService*  probe( IOService *provider, SInt32 *score );
244    virtual bool        start( IOService *provider );
245    virtual void        free( void );
246    virtual void        stop( IOService *provider );
247    virtual IOReturn    message( UInt32 type, IOService *provider,  void *argument = 0 );
248
249	/**** IOSerialDriverSync Abstract Method Implementation ****/
250
251    virtual IOReturn    acquirePort( bool sleep, void *refCon );
252    virtual IOReturn    releasePort( void *refCon );
253    virtual IOReturn    setState( UInt32 state, UInt32 mask, void *refCon );
254    virtual UInt32      getState( void *refCon );
255    virtual IOReturn    watchState( UInt32 *state, UInt32 mask, void *refCon );
256    virtual UInt32      nextEvent( void *refCon );
257    virtual IOReturn    executeEvent( UInt32 event, UInt32 data, void *refCon );
258    virtual IOReturn    requestEvent( UInt32 event, UInt32 *data, void *refCon );
259    virtual IOReturn    enqueueEvent( UInt32 event, UInt32 data, bool sleep, void *refCon );
260    virtual IOReturn    dequeueEvent( UInt32 *event, UInt32 *data, bool sleep, void *refCon );
261    virtual IOReturn    enqueueData( UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon );
262    virtual IOReturn    dequeueData( UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon );
263
264    // Power management routines
265    virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags );
266    virtual IOReturn    setPowerState(unsigned long powerStateOrdinal, IOService * whatDevice);
267
268	/**** AppleUSBIrDA Methods ****/
269	/**** IrDA Specific (Public) ****/
270
271    void            Add_RXBytes( UInt8 *Buffer, size_t Size );
272    SInt16          SetBofCount( SInt16 bof_count );
273    UInt16          SetSpeed( UInt32 brate );
274    bool            SetUpTransmit( void );
275    IOReturn        StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer );
276
277    IrDAComm*       GetIrDAComm( void );
278    void            GetIrDAStatus( IrDAStatus *status );
279    IOReturn        SetIrDAUserClientState( bool IrDAOn );
280    USBIrDAQoS*     GetIrDAQoS( void );
281
282private:
283
284	/**** Queue primatives ****/
285
286    QueueStatus     AddBytetoQueue( CirQueue *Queue, char Value );
287    QueueStatus     GetBytetoQueue( CirQueue *Queue, UInt8 *Value );
288    QueueStatus     InitQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size );
289    QueueStatus     CloseQueue( CirQueue *Queue );
290    size_t          AddtoQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size );
291    size_t          RemovefromQueue( CirQueue *Queue, UInt8 *Buffer, size_t MaxSize );
292    size_t          FreeSpaceinQueue( CirQueue *Queue );
293    size_t          UsedSpaceinQueue( CirQueue *Queue );
294    size_t          GetQueueSize( CirQueue *Queue );
295    //QueueStatus       GetQueueStatus( CirQueue *Queue );
296    void            CheckQueues( PortInfo_t *port );
297
298	/**** State manipulations ****/
299
300    IOReturn        privateWatchState( PortInfo_t *port, UInt32 *state, UInt32 mask );
301    UInt32          readPortState( PortInfo_t *port );
302    void            changeState( PortInfo_t *port, UInt32 state, UInt32 mask );
303    IOReturn        CheckIrDAState();       // combines fSessions, fStartStopUserClient, fStartStopUSB to new state
304
305	/**** USB Specific ****/
306
307    bool            configureDevice( UInt8 numConfigs );
308    void            Workaround();                               // reset confused silicon
309
310    bool            allocateResources( void );                  // allocate pipes
311    void            releaseResources( void );                   // free pipes
312    bool            startPipes();                               // start the usb reads going
313    void            stopPipes();
314    bool            createSerialStream();                       // create bsd stream
315    void            destroySerialStream();                      // delete bsd stream
316    bool            createSuffix( unsigned char *sufKey, int sufMaxLen );
317    bool            startIrDA();                                // start irda up
318    void            stopIrDA();                                 // shut down irda
319    bool            createNub();                                // create nub (and port)
320    void            destroyNub();
321    void            SetStructureDefaults( PortInfo_t *port, bool Init );
322    bool            allocateRingBuffer( CirQueue *Queue, size_t BufferSize );
323    void            freeRingBuffer( CirQueue *Queue );
324
325}; /* end class AppleUSBIrDADriver */
326
327#endif
328