1/*
2 * Copyright (c) 1998-2002 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 *  IOFWUserClientPsdoAddrSpace.h
24 *  IOFireWireFamily
25 *
26 *  Created by NWG on Fri Dec 08 2000.
27 *  Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
28 *
29 */
30/*
31	$Log: IOFWUserPseudoAddressSpace.h,v $
32	Revision 1.12  2009/10/16 23:59:06  calderon
33	<rdar://problem/7046489> 10A402 AsyncTester results in Error-Server verified Incorrect number of bytes
34	<rdar://problem/7111060> PanicTracer: 3 panics at IOFireWireFamily : IOFWUserPseudoAddressSpace::doPacket
35
36	And some help for:
37	<rdar://problem/7116134> PanicTracer: 3 panics at com.apple.iokit.IOFireWireFamily
38
39	Revision 1.11  2008/09/12 23:44:05  calderon
40	<rdar://5971979/> PseudoAddressSpace skips/mangles packets
41	<rdar://5708169/> FireWire synchronous commands' headerdoc missing callback info
42
43	Revision 1.10  2008/07/04 00:09:14  arulchan
44	fix for rdar://6035774
45
46	Revision 1.9  2007/02/16 19:03:44  arulchan
47	*** empty log message ***
48
49	Revision 1.8  2007/02/14 21:58:29  collin
50	*** empty log message ***
51
52	Revision 1.7  2007/02/07 06:35:20  collin
53	*** empty log message ***
54
55	Revision 1.6  2006/12/21 21:17:44  ayanowit
56	More changes necessary to eventually get support for 64-bit apps working (4222965).
57
58	Revision 1.5  2006/12/06 19:21:49  arulchan
59	*** empty log message ***
60
61	Revision 1.4  2003/07/24 06:30:58  collin
62	*** empty log message ***
63
64	Revision 1.3  2003/07/21 06:52:59  niels
65	merge isoch to TOT
66
67	Revision 1.2.14.1  2003/07/01 20:54:07  niels
68	isoch merge
69
70	Revision 1.2  2002/10/18 23:29:44  collin
71	fix includes, fix cast which fails on new compiler
72
73	Revision 1.1  2002/09/25 00:27:22  niels
74	flip your world upside-down
75
76	Revision 1.11  2002/08/06 19:42:54  niels
77	now send conflict response if user pseudo address space can't receive a write because the queue is full in cases where the hardware has not already responded 'ack complete'
78
79*/
80
81#ifndef __IOFWUserClientPsduAddrSpace_H__
82#define __IOFWUserClientPsduAddrSpace_H__
83
84// public
85#import <IOKit/firewire/IOFireWireFamilyCommon.h>
86#import <IOKit/firewire/IOFWAddressSpace.h>
87
88// private
89#import "IOFireWireLibPriv.h"
90#import "IOFWRingBufferQ.h"
91
92using namespace IOFireWireLib ;
93
94typedef union IOFWPacketHeader_t
95{
96    typedef enum
97    {
98        kFree = 0,
99        kStopPacket   	  	= 'stop',
100        kBadPacket	   		= ' bad',
101        kIncomingPacket	 	= 'pckt',
102        kSkippedPacket		= 'skip',
103		kReadPacket			= 'read',
104		kLockPacket			= 'lock'
105    } QueueTag ;
106
107    struct
108    {
109        QueueTag 					type ;
110        IOFWPacketHeader_t*			next ;
111        OSAsyncReference64*			whichAsyncRef ;
112        UInt32						argCount ;
113        io_user_reference_t			headerSize ;		// only valid for skipped packets
114		io_user_reference_t			headerOffset ;		// only valid for skipped packets
115
116        io_user_reference_t			args[9] ;
117    } CommonHeader ;
118
119    struct
120    {
121        // -----------------------------------------------
122        QueueTag					type ;
123        IOFWPacketHeader_t*			next ;
124        OSAsyncReference64*			whichAsyncRef ;
125        UInt32						argCount ;
126		io_user_reference_t			headerSize ;		// only valid for skipped packets
127		io_user_reference_t			headerOffset ;		// only valid for skipped packets
128        // -----------------------------------------------
129
130        io_user_reference_t			commandID ;			//	0
131        io_user_reference_t			packetSize ;		//	1
132        io_user_reference_t			packetOffset ;		//	2
133        io_user_reference_t			nodeID ;
134        io_user_reference_t			speed ;
135        io_user_reference_t			addrHi ;
136        io_user_reference_t			addrLo ;
137        io_user_reference_t			isLock ;
138		io_user_reference_t			generation ;
139		io_user_reference_t			reqrefcon ;
140
141    } IncomingPacket ;
142
143    struct SkippedPacket_t
144    {
145        // -----------------------------------------------
146        QueueTag 					type ;
147        IOFWPacketHeader_t*			next ;
148        OSAsyncReference64*			whichAsyncRef ;
149        UInt32						argCount ;
150		io_user_reference_t			headerSize ;		// only valid for skipped packets
151		io_user_reference_t			headerOffset ;		// only valid for skipped packets
152        // -----------------------------------------------
153
154        io_user_reference_t					commandID ;			//	0
155        io_user_reference_t					skippedPacketCount ;
156    } SkippedPacket ;
157
158	struct ReadPacket_t
159	{
160	    // -----------------------------------------------
161	    QueueTag 					type ;
162		IOFWPacketHeader_t*			next ;
163		OSAsyncReference64*			whichAsyncRef ;
164		UInt32						argCount ;
165		io_user_reference_t			headerSize ;		// only valid for skipped packets
166		io_user_reference_t			headerOffset ;		// only valid for skipped packets
167		// -----------------------------------------------
168
169        io_user_reference_t			commandID ;			//	0
170        io_user_reference_t			packetSize ;		//	1
171        io_user_reference_t			packetOffset ;		//	2
172        io_user_reference_t			nodeID ;
173        io_user_reference_t			speed ;
174        io_user_reference_t			addrHi ;
175        io_user_reference_t			addrLo ;
176		io_user_reference_t			reqrefcon ;
177		io_user_reference_t			generation ;
178	} ReadPacket ;
179
180public:
181    IOFWPacketHeader_t() ;
182
183} IOFWPacketHeader ;
184
185io_user_reference_t& IOFWPacketHeaderGetSize(IOFWPacketHeader_t* hdr) ;
186io_user_reference_t& IOFWPacketHeaderGetOffset(IOFWPacketHeader_t* hdr) ;
187void InitIncomingPacketHeader(
188	IOFWPacketHeader_t*				header,
189	IOFWPacketHeader_t*				next,
190	const IOByteCount				len,
191	const IOByteCount				offset,
192	OSAsyncReference64*				ref,
193	UInt16							nodeID,
194	const IOFWSpeed&   				speed,
195	const FWAddress&				addr,
196	const bool						isLock = false) ;	// generation used only for lock
197inline void InitSkippedPacketHeader(
198	IOFWPacketHeader*				header,
199	const union IOFWPacketHeader_t* next,
200	const IOByteCount				offset,
201	OSAsyncReference64*				ref) ;
202inline void InitReadPacketHeader(
203	IOFWPacketHeader*				header,
204	IOFWPacketHeader*				next,
205	UInt32							len,
206	UInt32							offset,
207	OSAsyncReference64*				ref,
208	void*							refCon,
209	UInt16							nodeID,
210	IOFWSpeed&						speed,
211	FWAddress						addr,
212	IOFWRequestRefCon				reqrefcon) ;
213inline void	InitLockPacketHeader(
214	IOFWPacketHeader*				header,
215	IOFWPacketHeader*				next,
216	IOByteCount						len,
217	IOByteCount						offset,
218	OSAsyncReference64*				ref,
219	UInt16							nodeID,
220	IOFWSpeed&						speed,
221	FWAddress						addr,
222	const UInt32					generation,
223	IOFWRequestRefCon				reqrefcon) ;
224inline Boolean IsSkippedPacketHeader(const union IOFWPacketHeader_t* header) ;
225inline Boolean IsFreePacketHeader(const union IOFWPacketHeader_t* header) ;
226//inline Boolean IsReadPacketHeader(const union IOFWPacketHeader_t* header) ;
227
228class IOFireWireUserClient ;
229
230// To support mapping the memory descriptor within
231// a pseudo address space to user space, we need to add
232// accessors to IOFWPseudoAddressSpace. This class
233// implements the additional functionality.
234class IOFWUserPseudoAddressSpace: public IOFWPseudoAddressSpace
235{
236	OSDeclareDefaultStructors(IOFWUserPseudoAddressSpace)
237
238public:
239	// --- OSObject ----------
240#if IOFIREWIREUSERCLIENTDEBUG > 0
241    virtual bool 						serialize(OSSerialize *s) const;
242#endif
243	virtual void						free() ;
244	static void							exporterCleanup( const OSObject * self );
245
246	// --- IOFWPseudoAddressSpace ----------
247	// override deactivate so we can delete any notification related structures...
248	virtual void						deactivate() ;
249
250	bool							completeInit( IOFireWireUserClient* userclient, AddressSpaceCreateParams* params ) ;
251	bool							initPseudo( IOFireWireUserClient* userclient, AddressSpaceCreateParams* params ) ;
252	bool							initFixed( IOFireWireUserClient* userclient, AddressSpaceCreateParams* params ) ;
253	virtual UInt32 					doLock(
254											UInt16 						nodeID,
255											IOFWSpeed &					speed,
256											FWAddress 					addr,
257											UInt32 						inLen,
258											const UInt32 *				newVal,
259											UInt32 &					outLen,
260											UInt32 *					oldVal,
261											UInt32 						type,
262											IOFWRequestRefCon 			refcon) ;
263
264	UInt32							doPacket(
265											UInt16							nodeID,
266											IOFWSpeed&						speed,
267											FWAddress						addr,
268											UInt32							len,
269											const void*						buf,
270											IOFWRequestRefCon				reqrefcon,
271											IOFWPacketHeader::QueueTag		tag,
272											UInt32*							oldVal = NULL) ;
273
274	// --- getters ----------
275    const FWAddress& 				getBase() { return fAddress ; }
276	const UInt32					getUserRefCon() { return fUserRefCon ;}
277	const IOFireWireUserClient&				getUserClient() { return *fUserClient ;}
278
279	// --- readers/writers ----------
280    static UInt32					pseudoAddrSpaceReader(
281                                            void*					refCon,
282                                            UInt16					nodeID,
283                                            IOFWSpeed& 				speed,
284                                            FWAddress 				addr,
285                                            UInt32		 			len,
286                                            IOMemoryDescriptor**	buf,
287                                            IOByteCount* 			offset,
288                                            IOFWRequestRefCon		reqrefcon) ;
289    static UInt32					pseudoAddrSpaceWriter(
290                                            void*					refCon,
291                                            UInt16					nodeID,
292                                            IOFWSpeed&				speed,
293                                            FWAddress				addr,
294                                            UInt32					len,
295                                            const void*				buf,
296                                            IOFWRequestRefCon		reqrefcon) ;
297
298	// --- async utility functions ----------
299	void							setAsyncRef_Packet(
300											OSAsyncReference64		inAsyncRef) ;
301	void							setAsyncRef_SkippedPacket(
302											OSAsyncReference64		inAsyncRef) ;
303	void							setAsyncRef_Read(
304											OSAsyncReference64		inAsyncRef) ;
305	void							clientCommandIsComplete(
306											FWClientCommandID		inCommandID,
307											IOReturn				inResult ) ;
308	void							sendPacketNotification(
309											IOFWPacketHeader*		inPacketHeader) ;
310private:
311	IOFWRingBufferQ *			fPacketQueue;					// the queue where incoming packets go before being written to the backingstore
312	IOLock*						fLock ;							// to lock this object
313
314	mach_vm_address_t			fUserRefCon ;
315	IOFireWireUserClient*		fUserClient ;
316	IOFWPacketHeader*			fLastWrittenHeader ;
317	IOFWPacketHeader*			fLastReadHeader ;
318	FWAddress					fAddress ;						// where we are
319
320	OSAsyncReference64			fSkippedPacketAsyncNotificationRef ;
321	OSAsyncReference64			fPacketAsyncNotificationRef ;
322	OSAsyncReference64			fReadAsyncNotificationRef ;
323	bool						fWaitingForUserCompletion ;
324	bool						fUserLocks ;					// are we doing locks in user space?
325
326	UInt32						fFlags ;
327
328	Boolean						fPacketQueuePrepared ;
329	Boolean						fBackingStorePrepared ;
330} ;
331
332#endif //__IOFWUserClientPsduAddrSpace_H__
333