1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * Copyright (c) 1998-2004 Apple Computer, Inc.  All Rights Reserved.
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25#ifndef __APPLEUSBCDCDMM__
26#define __APPLEUSBCDCDMM__
27
28#include "AppleUSBCDCCommon.h"
29#include "AppleUSBCDC.h"
30
31    // Common Defintions
32
33#define LDEBUG		0			// for debugging
34#define USE_ELG		0			// to Event LoG (via kprintf and Firewire) - LDEBUG must also be set
35#define USE_IOL		0			// to IOLog - LDEBUG must also be set
36#define	LOG_DATA	0			// logs data to the appropriate log - LDEBUG must also be set
37#define DUMPALL		0			// Dumps all the data to the log - LOG_DATA must also be set
38
39#define Sleep_Time	20
40
41#define Log IOLog
42#if USE_ELG
43	#undef Log
44	#define Log	kprintf
45#endif
46
47#if LDEBUG
48    #if USE_ELG
49		#define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B));}
50		#define XTRACEP(ID,A,B,STRING) {Log("%8p %8p %8p " DEBUG_NAME ": " STRING "\n",(void *)(ID),(void *)(A),(void *)(B));}
51    #else /* not USE_ELG */
52        #if USE_IOL
53            #define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B)); IOSleep(Sleep_Time);}
54			#define XTRACEP(ID,A,B,STRING) {Log("%8p %8p %8p " DEBUG_NAME ": " STRING "\n",(void *)(ID),(void *)(A),(void *)(B)); IOSleep(Sleep_Time);}
55        #else
56            #define XTRACE(id, x, y, msg)
57			#define XTRACEP(id, x, y, msg)
58        #endif /* USE_IOL */
59    #endif /* USE_ELG */
60    #if LOG_DATA
61        #define LogData(D, C, b)	USBLogData((UInt8)D, (SInt32)C, (char *)b)
62        #define meLogData(D, C, b)	me->USBLogData((UInt8)D, (SInt32)C, (char *)b)
63    #else /* not LOG_DATA */
64        #define LogData(D, C, b)
65        #define meLogData(D, C, b)
66    #endif /* LOG_DATA */
67#else /* not LDEBUG */
68    #define XTRACE(id, x, y, msg)
69	#define XTRACEP(id, x, y, msg)
70    #define LogData(D, C, b)
71    #define meLogData(D, C, b)
72    #undef USE_ELG
73    #undef USE_IOL
74    #undef LOG_DATA
75#endif /* LDEBUG */
76
77#define ALERT(A,B,STRING)	Log("%8x %8x " DEBUG_NAME ": " STRING "\n", (unsigned int)(A), (unsigned int)(B))
78
79enum
80{
81    kDataIn 		= 0,
82    kDataOut,
83    kDataOther
84};
85
86#define baseName		"dmmcontrol"
87#define defaultName		"USB Modem"
88#define productNameLength	32						// Arbitrary length
89#define propertyTag		"Product Name"
90#define hiddenTag		"HiddenPort"
91
92#define kDefaultBaudRate	9600
93#define kMaxBaudRate		230400
94#define kMaxCirBufferSize	4096
95
96    // USB CDC DMM Defintions
97
98#define kUSBbRxCarrier			0x01			// Carrier Detect
99#define kUSBDCD				kUSBbRxCarrier
100#define kUSBbTxCarrier			0x02			// Data Set Ready
101#define kUSBDSR				kUSBbTxCarrier
102#define kUSBbBreak			0x04
103#define kUSBbRingSignal			0x08
104#define kUSBbFraming			0x10
105#define kUSBbParity			0x20
106#define kUSBbOverRun			0x40
107
108#define kDTROff				0
109#define kRTSOff				0
110#define kDTROn				1
111#define kRTSOn				2
112
113typedef struct
114{
115    UInt32	dwDTERate;
116    UInt8	bCharFormat;
117    UInt8	bParityType;
118    UInt8	bDataBits;
119} LineCoding;
120
121#define dwDTERateOffset	0
122
123#define wValueOffset	2
124#define wIndexOffset	4
125#define wLengthOffset	6
126
127    // SccQueuePrimatives.h
128
129typedef struct CirQueue
130{
131    UInt8	*Start;
132    UInt8	*End;
133    UInt8	*NextChar;
134    UInt8	*LastChar;
135    size_t	Size;
136    size_t	InQueue;
137} CirQueue;
138
139typedef enum QueueStatus
140{
141    queueNoError = 0,
142    queueFull,
143    queueEmpty,
144    queueMaxStatus
145} QueueStatus;
146
147    // Miscellaneous
148
149#define BIGGEST_EVENT		3
150
151#define SPECIAL_SHIFT		(5)
152#define SPECIAL_MASK		((1<<SPECIAL_SHIFT) - 1)
153#define STATE_ALL		(PD_RS232_S_MASK | PD_S_MASK)
154#define FLOW_RX_AUTO   	 	(PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO)
155#define FLOW_TX_AUTO    	(PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD)
156#define CAN_BE_AUTO		(FLOW_RX_AUTO | FLOW_TX_AUTO)
157#define CAN_NOTIFY		(PD_RS232_N_MASK)
158#define EXTERNAL_MASK   	(PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP))
159#define INTERNAL_DELAY  	(PD_RS232_S_LOOP)
160#define DEFAULT_AUTO		(PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR)
161#define DEFAULT_NOTIFY		0x00
162#define DEFAULT_STATE		(PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO)
163
164#define IDLE_XO	   		 0
165#define NEEDS_XOFF 		 1
166#define SENT_XOFF 		-1
167#define NEEDS_XON  		 2
168#define SENT_XON  		-2
169
170#define INT_BUFF_SIZE	16
171
172typedef struct
173{
174    UInt32	ints;
175    UInt32	txInts;
176    UInt32	rxInts;
177    UInt32	mdmInts;
178    UInt32	txChars;
179    UInt32	rxChars;
180} Stats_t;
181
182typedef struct BufferMarks
183{
184    unsigned long	BufferSize;
185    unsigned long	HighWater;
186    unsigned long	LowWater;
187    bool		OverRun;
188} BufferMarks;
189
190typedef struct
191{
192
193        // State and serialization variables
194
195    UInt32		State;
196    UInt32		WatchStateMask;
197
198        // queue control structures:
199
200    CirQueue		RX;
201    CirQueue		TX;
202
203    BufferMarks		RXStats;
204    BufferMarks		TXStats;
205
206        // UART configuration info:
207
208    UInt32		CharLength;
209    UInt32		StopBits;
210    UInt32		TX_Parity;
211    UInt32		RX_Parity;
212    UInt32		BaudRate;
213    UInt8		FCRimage;
214    UInt8		IERmask;
215    bool            	MinLatency;
216
217        // flow control state & configuration:
218
219    UInt8		XONchar;
220    UInt8		XOFFchar;
221    UInt32		SWspecial[ 0x100 >> SPECIAL_SHIFT ];
222    UInt32		FlowControl;			// notify-on-delta & auto_control
223
224    SInt16		RXOstate;    			// Indicates our receive state.
225    SInt16		TXOstate;			// Indicates our transmit state, if we have received any Flow Control.
226
227    IOThread		FrameTOEntry;
228
229    mach_timespec	DataLatInterval;
230    mach_timespec	CharLatInterval;
231
232        // extensions for USB Driver
233
234//    UInt8		InterfaceNumber;
235
236    UInt32		OutPacketSize;
237    UInt32		InPacketSize;
238
239    UInt32		LastCharLength;
240    UInt32		LastStopBits;
241    UInt32		LastTX_Parity;
242    UInt32		LastBaudRate;
243
244} PortInfo_t;
245
246	/* AppleUSBCDCDMM.h - This file contains the class definition for the		*/
247	/* USB Communication Device Class (CDC) DMM Interface driver.			*/
248
249class AppleUSBCDCDMM : public IOSerialDriverSync
250{
251    OSDeclareDefaultStructors(AppleUSBCDCDMM);			// Constructor & Destructor stuff
252
253private:
254    UInt16				fSessions;				// Number of active sessions
255    bool				fTerminate;				// Are we being terminated (ie the device was unplugged)
256    bool				fStopping;				// Are we being "stopped"
257    UInt8				fProductName[productNameLength];	// Product String from the Device
258
259	bool				fReadDead;				// Is the interrupt pipe read dead
260    IOUSBPipe			*fIntPipe;				// The interrupt pipe
261    IOBufferMemoryDescriptor	*fIntPipeMDP;		// Interrupt pipe memory descriptor
262    UInt8				*fIntPipeBuffer;			// Interrupt pipe buffer
263	UInt16				fIntBufferSize;				// Size of the interrupt buffer
264    IOUSBCompletion		fIntCompletionInfo;			// Interrupt completion routine
265    IOUSBCompletion		fMERCompletionInfo;			// MER completion routine
266	IOUSBCompletion		fRspCompletionInfo;			// Response completion routine
267	UInt8				fInterfaceNumber;			// My interface number
268
269	UInt8			*fInBuffer;
270	UInt8			*fOutBuffer;
271
272	static void		intReadComplete(void *obj, void *param, IOReturn rc, UInt32 remaining);
273    static void		merWriteComplete(void *obj, void *param, IOReturn rc, UInt32 remaining);
274	static void		rspComplete(void *obj, void *param, IOReturn rc, UInt32 remaining);
275
276public:
277
278    IOUSBInterface		*fInterface;
279    IOWorkLoop			*fWorkLoop;
280    IOCommandGate		*fCommandGate;
281    PortInfo_t 			fPort;					// Port structure
282
283	UInt16			fMax_Command;				// maximum command size
284
285//    UInt8			fConfigAttributes;			// Configuration descriptor attributes
286
287        // IOKit methods:
288
289	virtual IOService   *probe(IOService *provider, SInt32 *score);
290    virtual bool		start(IOService *provider);
291    virtual void		stop(IOService *provider);
292    virtual IOReturn 		message(UInt32 type, IOService *provider,  void *argument = 0);
293
294        // IOSerialDriverSync Abstract Method Implementation
295
296    virtual IOReturn		acquirePort(bool sleep, void *refCon);
297    virtual IOReturn		releasePort(void *refCon);
298    virtual UInt32			getState(void *refCon);
299    virtual IOReturn		setState(UInt32 state, UInt32 mask, void *refCon);
300    virtual IOReturn		watchState(UInt32 *state, UInt32 mask, void *refCon);
301    virtual UInt32			nextEvent(void *refCon);
302    virtual IOReturn		executeEvent(UInt32 event, UInt32 data, void *refCon);
303    virtual IOReturn		requestEvent(UInt32 event, UInt32 *data, void *refCon);
304    virtual IOReturn		enqueueEvent(UInt32 event, UInt32 data, bool sleep, void *refCon);
305    virtual IOReturn		dequeueEvent(UInt32 *event, UInt32 *data, bool sleep, void *refCon);
306    virtual IOReturn		enqueueData(UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon);
307    virtual IOReturn		dequeueData(UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon);
308
309        // Static stubs for IOCommandGate::runAction
310
311    static	IOReturn	stopAction(OSObject *owner, void *, void *, void *, void *);
312    static	IOReturn	acquirePortAction(OSObject *owner, void *arg0, void *, void *, void *);
313    static	IOReturn	releasePortAction(OSObject *owner, void *, void *, void *, void *);
314    static	IOReturn	getStateAction(OSObject *owner, void *, void *, void *, void *);
315    static	IOReturn	setStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
316    static	IOReturn	watchStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
317    static	IOReturn	executeEventAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
318    static	IOReturn	enqueueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3);
319    static	IOReturn	dequeueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3);
320
321        // Gated methods called by the Static stubs
322
323    virtual	void		stopGated(void);
324    virtual	IOReturn	acquirePortGated(bool sleep);
325    virtual	IOReturn	releasePortGated(void);
326    virtual	UInt32		getStateGated(void);
327    virtual	IOReturn	setStateGated(UInt32 *pState, UInt32 *pMask);
328    virtual	IOReturn	watchStateGated(UInt32 *state, UInt32 *pMask);
329    virtual	IOReturn	executeEventGated(UInt32 *event, UInt32 *data);
330    virtual	IOReturn	enqueueDataGated(UInt8 *buffer, UInt32 *pSize, UInt32 *count, bool *pSleep);
331    virtual	IOReturn	dequeueDataGated(UInt8 *buffer, UInt32 *pSize, UInt32 *count, UInt32 *pMin);
332
333        // DMM Driver Methods
334
335    void			USBLogData(UInt8 Dir, SInt32 Count, char *buf);
336	bool			configureDMM(void);
337	bool			getFunctionalDescriptors(void);
338    bool 			createSuffix(unsigned char *sufKey);
339    bool			createSerialStream(void);
340    bool 			setUpTransmit(void);
341    void 			startTransmission(void);
342	IOReturn		sendMERRequest(UInt8 request, UInt16 val, UInt16 len, UInt8 *buff, IOUSBCompletion *Comp);
343    void 			setLineCoding(void);
344    void 			setControlLineState(bool RTS, bool DTR);
345    void 			sendBreak(bool sBreak);
346    IOReturn		checkPipe(IOUSBPipe *thePipe, bool devReq);
347    void 			initStructure(void);
348    void 			setStructureDefaults(void);
349    bool 			allocateResources(void);
350    void			releaseResources(void);
351    void 			freeRingBuffer(CirQueue *Queue);
352    bool 			allocateRingBuffer(CirQueue *Queue, size_t BufferSize);
353
354private:
355
356	// QueuePrimatives
357
358    QueueStatus			AddBytetoQueue(CirQueue *Queue, char Value);
359    QueueStatus			GetBytetoQueue(CirQueue *Queue, UInt8 *Value);
360    QueueStatus			InitQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size);
361    QueueStatus			CloseQueue(CirQueue *Queue);
362    size_t 			AddtoQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size);
363    size_t 			RemovefromQueue(CirQueue *Queue, UInt8 *Buffer, size_t MaxSize);
364    size_t 			FreeSpaceinQueue(CirQueue *Queue);
365    size_t 			UsedSpaceinQueue(CirQueue *Queue);
366    size_t 			GetQueueSize(CirQueue *Queue);
367    QueueStatus 		GetQueueStatus(CirQueue *Queue);
368	UInt16			isCRinQueue(CirQueue *Queue);
369    void 			CheckQueues(void);
370
371}; /* end class AppleUSBCDCDMM */
372#endif