1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * Copyright (c) 1998-2003 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 __APPLEUSBCDCACMData__
26#define __APPLEUSBCDCACMData__
27
28#include <IOKit/IOUserClient.h>
29
30#include "AppleUSBCDCCommon.h"
31#include "AppleUSBCDC.h"
32#include "AppleUSBCDCACMControl.h"
33#include "AppleUSBCDCACMDataUser.h"
34
35#define baseName		"usbmodem"
36#define hiddenTag		"HiddenPort"
37#define WWANTag			"WWAN"
38
39#define defaultName		"USB Modem"
40#define productNameLength	32						// Arbitrary length
41#define propertyTag		"Product Name"
42
43#define kDefaultBaudRate	9600
44#define kMaxBaudRate		6000000
45//#define kMaxBaudRate		230400
46//#define kMaxCirBufferSize	4096
47#define kMaxCirBufferSize	PAGE_SIZE*125       //rcs Bump every thing by *3*2x
48
49    // Default and Maximum buffer pool values
50
51#define kInBufPool		4*2
52#define kOutBufPool		2*2
53
54#define kMaxInBufPool		kInBufPool*16*2
55#define kMaxOutBufPool		kOutBufPool*8*2
56
57#define	inputTag		"InputBuffers"
58#define	outputTag		"OutputBuffers"
59
60    // SccQueuePrimatives.h
61
62typedef struct CirQueue
63{
64    UInt8	*Start;
65    UInt8	*End;
66    UInt8	*NextChar;
67    UInt8	*LastChar;
68    size_t	Size;
69    size_t	InQueue;
70} CirQueue;
71
72typedef enum QueueStatus
73{
74    queueNoError = 0,
75    queueFull,
76    queueEmpty,
77    queueMaxStatus
78} QueueStatus;
79
80    // Miscellaneous
81
82#define BIGGEST_EVENT		3
83
84#define SPECIAL_SHIFT		(5)
85#define SPECIAL_MASK		((1<<SPECIAL_SHIFT) - 1)
86#define STATE_ALL		(PD_RS232_S_MASK | PD_S_MASK)
87#define FLOW_RX_AUTO   	 	(PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO)
88#define FLOW_TX_AUTO    	(PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD)
89#define CAN_BE_AUTO		(FLOW_RX_AUTO | FLOW_TX_AUTO)
90#define CAN_NOTIFY		(PD_RS232_N_MASK)
91#define EXTERNAL_MASK   	(PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP))
92#define INTERNAL_DELAY  	(PD_RS232_S_LOOP)
93#define DEFAULT_AUTO		(PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR)
94#define DEFAULT_NOTIFY		0x00
95#define DEFAULT_STATE		(PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO)
96
97#define IDLE_XO	   		 0
98#define NEEDS_XOFF 		 1
99#define SENT_XOFF 		-1
100#define NEEDS_XON  		 2
101#define SENT_XON  		-2
102
103#define MAX_BLOCK_SIZE	PAGE_SIZE
104#define COMM_BUFF_SIZE	16
105#define DATA_BUFF_SIZE	1024
106
107typedef struct
108{
109    UInt32	ints;
110    UInt32	txInts;
111    UInt32	rxInts;
112    UInt32	mdmInts;
113    UInt32	txChars;
114    UInt32	rxChars;
115} Stats_t;
116
117typedef struct BufferMarks
118{
119    unsigned long	BufferSize;
120    unsigned long	HighWater;
121    unsigned long	LowWater;
122    bool		OverRun;
123} BufferMarks;
124
125typedef struct
126{
127    IOBufferMemoryDescriptor	*pipeMDP;
128    UInt8			*pipeBuffer;
129    SInt32			count;
130    bool			dead;
131	bool			held;
132    IOUSBCompletion		completionInfo;
133} inPipeBuffers;
134
135typedef struct
136{
137    IOBufferMemoryDescriptor	*pipeMDP;
138    UInt8			*pipeBuffer;
139    SInt32			count;
140    bool			avail;
141    IOUSBCompletion		completionInfo;
142} outPipeBuffers;
143
144typedef struct
145{
146
147        // State and serialization variables
148
149    UInt32		State;
150    UInt32		WatchStateMask;
151
152        // queue control structures:
153
154    CirQueue		RX;
155    CirQueue		TX;
156
157	inPipeBuffers	*holdQueue[kMaxInBufPool];
158	UInt16			holdQueueIndxIn;
159	UInt16			holdQueueIndxOut;
160
161    BufferMarks		RXStats;
162    BufferMarks		TXStats;
163
164        // UART configuration info:
165
166    UInt32		CharLength;
167    UInt32		StopBits;
168    UInt32		TX_Parity;
169    UInt32		RX_Parity;
170    UInt32		BaudRate;
171    UInt8		FCRimage;
172    UInt8		IERmask;
173    bool            	MinLatency;
174
175        // flow control state & configuration:
176
177    UInt8		XONchar;
178    UInt8		XOFFchar;
179    UInt32		SWspecial[ 0x100 >> SPECIAL_SHIFT ];
180    UInt32		FlowControl;			// notify-on-delta & auto_control
181
182    SInt16		RXOstate;    			// Indicates our receive state.
183    SInt16		TXOstate;			// Indicates our transmit state, if we have received any Flow Control.
184
185    IOThread		FrameTOEntry;
186
187    mach_timespec	DataLatInterval;
188    mach_timespec	CharLatInterval;
189
190        // extensions for USB Driver
191
192    IOUSBPipe		*InPipe;
193    IOUSBPipe		*OutPipe;
194
195    inPipeBuffers       inPool[kMaxInBufPool];
196    outPipeBuffers      outPool[kMaxOutBufPool];
197    UInt16		outPoolIndex;
198
199    UInt8		CommInterfaceNumber;
200    UInt8		DataInterfaceNumber;
201
202    UInt32		OutPacketSize;
203    UInt32		InPacketSize;
204
205    UInt32		LastCharLength;
206    UInt32		LastStopBits;
207    UInt32		LastTX_Parity;
208    UInt32		LastBaudRate;
209    bool        ringsAllocated;
210
211} PortInfo_t;
212
213class AppleUSBCDC;
214class AppleUSBCDCACMControl;
215
216	/* AppleUSBCDCACMData.h - This file contains the class definition for the		*/
217	/* USB Communication Device Class (CDC) Data Interface driver - ACM only at the moment.	*/
218
219class AppleUSBCDCACMData : public IOSerialDriverSync
220{
221    OSDeclareDefaultStructors(AppleUSBCDCACMData);			// Constructor & Destructor stuff
222
223private:
224	AppleUSBCDC		*fCDCDriver;			// The CDC driver
225	AppleUSBCDCACMControl   *fControlDriver;			// Our Control Driver
226    UInt16			fSessions;				// Number of active sessions
227    bool			fStopping;				// Are we being "stopped"
228    UInt8			fProductName[productNameLength];	// Product String from the Device
229	IOPMrootDomain	*fPMRootDomain;			// Power Management root domain
230	bool			fWoR;					// Wake on Ring flag
231	OSObject		*fWakeSettingControllerHandle;	// Wake setting handle
232
233    bool            fReady;                 // Are we ready to allow acquires
234
235    static void			dataReadComplete(void *obj, void *param, IOReturn ior, UInt32 remaining);
236    static void			dataWriteComplete(void *obj, void *param, IOReturn ior, UInt32 remaining);
237
238	void			handleSettingCallback(const OSSymbol *arg_type, OSObject *arg_val, uintptr_t refcon);
239
240public:
241
242    IOUSBInterface		*fDataInterface;
243    IOWorkLoop			*fWorkLoop;
244    IOCommandGate		*fCommandGate;
245    PortInfo_t 			fPort;					// Port structure
246
247    UInt16			fInBufPool;
248    UInt16			fOutBufPool;
249
250    UInt8			fConfigAttributes;			// Configuration descriptor attributes
251
252	bool			fTerminate;				// Are we being terminated (ie the device was unplugged)
253	bool			fResetOnClose;				// Do we need to reset the device on closing
254	bool			fEnumOnWake;				// Do we need to re-enumerate on wake
255	bool			fSuppressWarning;		// Are we suppressing the unplug warning dialog
256
257	OSBoolean		*fWanDevice;
258	OSDictionary	*fInterfaceMappings;
259
260	UInt16			fVendorID;				// Vendor ID
261    UInt16			fProductID;				// Product ID
262
263    SInt16			fThreadSleepCount;		// Count of number of threads currently asleep on the command gate
264
265	UInt32				bsdClientState;
266	IONotifier *		bsdClientAddedNotifier;
267
268        // IOKit methods:
269
270	virtual IOService   *probe(IOService *provider, SInt32 *score);
271    virtual bool		start(IOService *provider);
272    virtual void		stop(IOService *provider);
273    virtual bool		didTerminate(IOService *provider, IOOptionBits options, bool *defer);
274    virtual IOReturn 	message(UInt32 type, IOService *provider,  void *argument = 0);
275
276        // IOSerialDriverSync Abstract Method Implementation
277
278    virtual IOReturn		acquirePort(bool sleep, void *refCon);
279    virtual IOReturn		releasePort(void *refCon);
280    virtual UInt32		getState(void *refCon);
281    virtual IOReturn		setState(UInt32 state, UInt32 mask, void *refCon);
282    virtual IOReturn		watchState(UInt32 *state, UInt32 mask, void *refCon);
283    virtual UInt32		nextEvent(void *refCon);
284    virtual IOReturn		executeEvent(UInt32 event, UInt32 data, void *refCon);
285    virtual IOReturn		requestEvent(UInt32 event, UInt32 *data, void *refCon);
286    virtual IOReturn		enqueueEvent(UInt32 event, UInt32 data, bool sleep, void *refCon);
287    virtual IOReturn		dequeueEvent(UInt32 *event, UInt32 *data, bool sleep, void *refCon);
288    virtual IOReturn		enqueueData(UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon);
289    virtual IOReturn		dequeueData(UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon);
290	bool					findSerialBSDClient (IOModemSerialStreamSync *nub);
291
292        // Static stubs for IOCommandGate::runAction
293
294	static IOReturn			waitForBSDClienAction(OSObject *owner, void *, void *, void *, void *);
295    static bool				bsdClientPublished(AppleUSBCDCACMData *target, void *ref, IOService *newService,IONotifier * notifier);
296    static	IOReturn	stopAction(OSObject *owner, void *, void *, void *, void *);
297    static	IOReturn	acquirePortAction(OSObject *owner, void *arg0, void *, void *, void *);
298    static	IOReturn	releasePortAction(OSObject *owner, void *, void *, void *, void *);
299    static	IOReturn	getStateAction(OSObject *owner, void *, void *, void *, void *);
300    static	IOReturn	setStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
301    static	IOReturn	watchStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
302    static	IOReturn	executeEventAction(OSObject *owner, void *arg0, void *arg1, void *, void *);
303    static	IOReturn	enqueueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3);
304    static	IOReturn	dequeueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3);
305
306        // Gated methods called by the Static stubs
307
308	virtual IOReturn	waitForBSDClientGated(void);
309    virtual	void		stopGated(void);
310    virtual	IOReturn	acquirePortGated(bool sleep);
311    virtual	IOReturn	releasePortGated(void);
312    virtual	UInt32		getStateGated(void);
313    virtual	IOReturn	setStateGated(UInt32 *pState, UInt32 *pMask);
314    virtual	IOReturn	watchStateGated(UInt32 *pState, UInt32 *pMask);
315    virtual	IOReturn	executeEventGated(UInt32 *pEvent, UInt32 *pData);
316    virtual	IOReturn	enqueueDataGated(UInt8 *buffer, UInt32 *size, UInt32 *count, bool *pSleep);
317    virtual	IOReturn	dequeueDataGated(UInt8 *buffer, UInt32 *size, UInt32 *count, UInt32 *min);
318
319        // CDC Data Driver Methods
320
321    void			USBLogData(UInt8 Dir, SInt32 Count, char *buf);
322	void			dumpData(UInt8 Dir, char *buf, SInt32 Count);
323    bool 			createSuffix(unsigned char *sufKey);
324    bool			createSerialStream(void);
325    bool 			setUpTransmit(void);
326    void 			startTransmission(void);
327    void 			setLineCoding(void);
328    void 			setControlLineState(bool RTS, bool DTR);
329    void 			sendBreak(bool sBreak);
330    IOReturn		checkPipe(IOUSBPipe *thePipe, bool devReq);
331    void 			initStructure(void);
332    void 			setStructureDefaults(void);
333    bool 			allocateResources(void);
334    void			releaseResources(void);
335    void 			freeRingBuffer(CirQueue *Queue);
336    bool            createSerialRingBuffers();
337    bool 			allocateRingBuffer(CirQueue *Queue, size_t BufferSize);
338	bool			setupWakeOnRingPMCallback(void);
339    bool			WakeonRing(void);
340	void			setWakeFeature(void);
341	void			resurrectRead(void);
342    virtual void    clearSleepingThreads(void);
343
344	OSString		*getPortNameForInterface(UInt8 interfaceNumber);
345
346private:
347
348	// QueuePrimatives
349
350    QueueStatus			AddBytetoQueue(CirQueue *Queue, char Value);
351    QueueStatus			GetBytetoQueue(CirQueue *Queue, UInt8 *Value);
352    QueueStatus			InitQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size);
353    QueueStatus			CloseQueue(CirQueue *Queue);
354    size_t 			AddtoQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size);
355	size_t			AddtoRXQueue(CirQueue *Queue, inPipeBuffers *buffs, size_t Size);
356    size_t 			RemovefromQueue(CirQueue *Queue, UInt8 *Buffer, size_t MaxSize);
357    size_t 			FreeSpaceinQueue(CirQueue *Queue);
358    size_t 			UsedSpaceinQueue(CirQueue *Queue);
359    size_t 			GetQueueSize(CirQueue *Queue);
360    QueueStatus 		GetQueueStatus(CirQueue *Queue);
361    void 			CheckQueues(void);
362	void			CheckHold(void);
363
364}; /* end class AppleUSBCDCACMData */
365
366class AppleUSBCDCACMData;
367
368class AppleUSBCDCACMDataUserClient : public IOUserClient
369{
370    OSDeclareDefaultStructors(AppleUSBCDCACMDataUserClient);
371
372private:
373    AppleUSBCDCACMData	*fProvider;
374    IOExternalMethod	fMethods[1];		// just one method
375    task_t		fTask;
376
377public:
378    IOExternalMethod	*getTargetAndMethodForIndex(IOService **targetP, UInt32 index);
379    bool		initWithTask(task_t owningTask, void *security_id , UInt32 type);
380    bool		start(IOService *provider);
381    IOReturn		clientClose(void);
382    IOReturn		clientDied(void);
383    IOReturn		doRequest(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *outPutSize);
384
385private:
386    IOReturn		ACMDataOpen(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *pOutPutSize);
387    IOReturn		ACMDataClose(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *pOutPutSize);
388    IOReturn		ACMDataMessage(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *pOutPutSize);
389
390}; /* end class AppleUSBCDCACMDataUserClient */
391#endif