1/*
2 * Copyright (c) 1998-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/*!
24  @header IOFireWireSBP2ORB
25  Contains the class definition for IOFireWireSBP2ORB.
26*/
27
28#ifndef _IOKIT_IOFIREWIRESBP2ORB_H
29#define _IOKIT_IOFIREWIRESBP2ORB_H
30
31#include <IOKit/firewire/IOFireWireUnit.h>
32
33#include <IOKit/IOBufferMemoryDescriptor.h>
34#include <IOKit/IOUserClient.h>
35#include <IOKit/IODMACommand.h>
36
37enum
38{
39    kFWSBP2ConstraintForceDoubleBuffer		= (1 << 0)
40};
41
42// login option flags
43enum
44{
45    kFWSBP2CommandCompleteNotify			= (1 << 0),
46    kFWSBP2CommandTransferDataFromTarget	= (1 << 1),
47    kFWSBP2CommandImmediate					= (1 << 2),
48
49    kFWSBP2CommandNormalORB					= (1 << 5),
50    kFWSBP2CommandReservedORB				= (1 << 6),
51    kFWSBP2CommandVendorORB					= (1 << 7),
52    kFWSBP2CommandDummyORB					= (1 << 8),
53    kFWSBP2CommandCheckGeneration			= (1 << 9),
54
55	kFWSBP2CommandFixedSize					= (1 << 10),
56	kFWSBP2CommandVirtualORBs				= (1 << 11)     // handy for debugging
57};
58
59enum
60{
61    kFWSBP2MaxPageClusterSize = 0xf000
62};
63
64class IOFireWireSBP2ORB;
65class IOFireWireSBP2LUN;
66class IOFireWireSBP2Login;
67
68/*!
69    @class IOFireWireSBP2ORB
70    @abstract Represents an SBP2 normal command ORB.  Supplies the APIs for configuring normal
71    command ORBs.  This includes setting the command block and writing the page tables for I/O.
72    The ORBs are executed using the submitORB method in IOFireWireSBP2Login.
73*/
74
75class IOFireWireSBP2ORB : public IOCommand
76{
77    OSDeclareDefaultStructors( IOFireWireSBP2ORB )
78
79	friend class IOFireWireSBP2Login;
80	friend class IOFireWireSBP2ManagementORB;
81
82protected:
83
84    typedef struct
85    {
86        UInt32		nextORBAddressHi;
87        UInt32		nextORBAddressLo;
88        UInt32		dataDescriptorHi;
89        UInt32		dataDescriptorLo;
90        UInt16		options;
91        UInt16		dataSize;
92        UInt32		commandBlock[1];  // will be variable sized
93     } FWSBP2ORB;
94
95    typedef struct
96    {
97        UInt16		segmentLength;
98        UInt16		segmentBaseAddressHi;
99        UInt32		segmentBaseAddressLo;
100    } FWSBP2PTE;
101
102private:
103
104    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 0);
105    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 1);
106    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 2);
107    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 3);
108    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 4);
109    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 5);
110    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 6);
111    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 7);
112    OSMetaClassDeclareReservedUnused(IOFireWireSBP2ORB, 8);
113
114protected:
115
116    virtual void deallocateBufferAddressSpace( void );
117    virtual IOReturn allocateTimer( void );
118    virtual void deallocateTimer( void );
119
120    /*!
121		@function deallocatePageTable
122		@abstract Frees up memory allocated for the page table.
123		@discussion	Frees all memory associated with the page table.  Undoes what allocatePageTable does.
124        Calling allocatePageTable again will automatically deallocate the existing page table before
125        allocating a new one, so this method is not used in most cases.
126	*/
127
128    virtual void deallocatePageTable( void );
129
130protected:
131
132    // IOFireWireSBP2Login methods
133	virtual bool initWithLogin( IOFireWireSBP2Login * login );
134    virtual void setNextORBAddress( FWAddress address );
135
136public:
137
138    /*!
139		@function allocatePageTable
140		@abstract Allocates memory for the page table.
141		@discussion	Page table allocation is handle automatically by the ORB, except if the
142        kFWSBP2CommandFixedSize flags is set.  In this case we will fail to write a page table if we
143        need more page table space than we have already.  This method is exposed so these drivers
144        can preallocate as much page table as they need.  This is useful if your driver is part of
145        the paging path and cannot allow allocations to occur.
146        @param entryCount number of entries of page table to be allocated.
147	*/
148
149    virtual IOReturn allocatePageTable( UInt32 entryCount );
150
151protected:
152
153    virtual bool isTimerSet( void );
154    virtual void cancelTimer( void );
155
156protected:
157
158    // reserved for future use
159    struct ExpansionData { };
160    ExpansionData *reserved;
161
162    IOFireWireSBP2Login *	fLogin;
163    IOFireWireSBP2LUN * 	fLUN;
164    IOFireWireUnit *		fUnit;
165    IOFireWireController *	fControl;
166    IODMACommand *			fDMACommand;
167	void *					fUnused2;
168
169    UInt32			fCommandFlags;
170    UInt32			fMaxPayloadSize;
171    UInt32			fTimeoutDuration;
172    UInt32			fGeneration;
173    UInt64			fRefCon;
174
175	//
176    // orb
177    //
178
179	IOMemoryDescriptor *		fORBDescriptor;
180    FWSBP2ORB *					fORBBuffer;
181
182    FWAddress 					fORBPseudoAddress;
183    IOFWAddressSpace *			fORBPseudoAddressSpace;
184
185    IOFWAddressSpace *			fORBPhysicalAddressSpace;
186	FWAddress					fORBPhysicalAddress;
187
188	//
189    // page table
190    //
191
192	UInt32						fPageTableSize;
193    IOBufferMemoryDescriptor *	fPageTableDescriptor;
194
195    IOFWAddressSpace *			fPageTablePhysicalAddressSpace;
196	FWAddress					fPageTablePhysicalAddress;
197	UInt32						fPageTablePhysicalLength;
198
199	IOFWAddressSpace *			fPageTablePseudoAddressSpace;
200	FWAddress					fPageTablePseudoAddress;
201
202	//
203    // buffers
204    //
205
206	IOFWAddressSpace *		fBufferAddressSpace;
207    bool					fBufferAddressSpaceAllocated;
208    IOMemoryDescriptor *	fBufferDescriptor;
209
210	//
211    // timer
212    //
213
214	IOFWDelayCommand *		fTimeoutCommand;
215    bool					fTimeoutTimerSet;
216
217	bool					fInProgress;
218	bool					fIsAppended;
219
220    UInt32					fFetchAgentWriteRetries;
221    UInt32					fPTECount;
222    UInt32					fFetchAgentWriteRetryInterval;
223
224	UInt32					fConstraintOptions;
225
226    virtual IOReturn allocateResources( void );
227    virtual void free( void );
228
229    // orb timeout handler
230    static void orbTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
231    virtual void orbTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
232
233	// login friend class wrappers
234	virtual IOFireWireUnit * getFireWireUnit( void );
235	virtual IOFireWireSBP2LUN * getFireWireLUN( void );
236  	virtual void deallocateORB( void );
237	virtual IOReturn allocateORB( UInt32 orbSize );
238    virtual IOReturn removeORB( IOFireWireSBP2ORB * orb );
239    virtual void prepareORBForExecution( void );
240    virtual void startTimer( void );
241    virtual void sendTimeoutNotification( IOFireWireSBP2ORB * orb );
242
243public:
244
245    /*!
246        @function release
247        @abstract Primary implementation of the release mechanism.
248        @discussion See OSObject.h for more information.
249        @param when When retainCount == when then call free().
250    */
251
252	virtual void release() const;
253
254    /*!
255        @function getLogin
256        @abstract Gets the login associated with this ORB.
257        @discussion Returns the IOFireWireSBP2Login object associated with this ORB.
258        @result Returns a pointer to an IOFireWireSBP2Login.
259    */
260
261    virtual IOFireWireSBP2Login * getLogin( void );
262
263    /*!
264        @function setCommandBuffersAsRanges
265        @abstract Creates a page table from a list of ranges.
266        @discussion Creates a page table with the given parameters. Any addresses mapped by this method
267        must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called.
268        The SBP2 services do not release references to the command buffers just because the command
269        has completed.
270        @param ranges An array of ranges representing the data to be transfered.
271        @param withCount The number of ranges in the ranges array.
272        @param withDirection An IODirection indicating the direction of data transfer.
273        @param withTask The task that these adressses reside in.
274        @param offset Offset in bytes into data to begin writing table at.
275        @param length Number of bytes of data to map from offset.
276        @result Returns KIOReturnSuccess if the page table was written successfully.
277    */
278
279    virtual IOReturn setCommandBuffersAsRanges(  IOVirtualRange * ranges,
280                                                 UInt32           withCount,
281                                                 IODirection      withDirection,
282                                                 task_t           withTask,
283                                                 UInt32		offset = 0,
284                                                 UInt32		length = 0 );
285    /*!
286        @function setCommandBuffersAsRanges
287        @abstract Creates a page table from a list of ranges.
288        @discussion Creates a page table with the given parameters. Any addresses mapped by this method
289        must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called.
290        The SBP2 services do not release references to the command buffers just because the command
291        has completed.
292        @param memoryDescriptor IOMemoryDescriptor describe ranges to be written to a page table.
293        @param offset Offset in bytes into data to begin writing table at.
294        @param length Number of bytes of data to map from offset.
295        @result Returns KIOReturnSuccess if the page table was written successfully.
296    */
297
298    virtual IOReturn setCommandBuffers( IOMemoryDescriptor * memoryDescriptor, UInt32 offset = 0,
299																				UInt32 length = 0 );
300
301
302    /*!
303        @function releaseCommandBuffers
304        @abstract Releases SBP2's reference to the command buffers.
305        @discussion When you create a page table with one of the variants of setCommandBuffers.
306        SBP2 holds on to a reference to the buffers until this method is called.  This means that
307        if a command completed and you manipulated the memory descriptor or released the buffers
308        without calling this method you could leave FW in an inconsistent state.
309        @result Returns KIOReturnSuccess if the page table was cleared successfully.
310    */
311
312    virtual IOReturn releaseCommandBuffers( void );
313
314    /*!
315        @function setCommandBlock
316        @abstract Sets the command block portion of the ORB.
317        @discussion Copys the data provided in the buffer to the command block portion of the ORB.
318        @param buffer Pointer to buffer to copy command block from.
319        @param length Number of bytes of data to copy.
320        @result Returns KIOReturnSuccess if the command block was updated successfully.
321    */
322
323    virtual IOReturn setCommandBlock( void * buffer, UInt32 length );
324
325    /*!
326        @function setCommandBlock
327        @abstract Sets the command block portion of the ORB.
328        @discussion Copys the data provided in the buffer to the command block portion of the ORB.
329        @param memory IOMemoryDescriptor representing the command block buffer.
330        @result Returns KIOReturnSuccess if the command block was updated successfully.
331    */
332
333    virtual IOReturn setCommandBlock( IOMemoryDescriptor * memory );
334
335    /*!
336        @function getCommandBufferDescriptor
337        @abstract Returns the memory descriptor representing the command buffer.
338        @discussion Returns the IOMemoryDescriptor for the data mapped by setCommandBuffer variants.
339        Works for setCommandBuffersAsRanges too.
340        @result Returns memory descriptor representing mapped data buffers.
341    */
342
343	virtual IOMemoryDescriptor * getCommandBufferDescriptor( void );
344
345    // accessors
346
347    /*!
348        @function setCommandFlags
349        @abstract Sets configuration flags for the ORB.
350        @discussion Sets the configuration flags for the ORB.  These can be any of the following:
351		<p>kFWSBP2CommandCompleteNotify - Set the notify bit as specified in SBP2 standard. Set to receive completion/timeout notification on this ORB.  You almost always want to set this.</p>
352		<p>kFWSBP2CommandTransferDataFromTarget - Transfer direction as specified in SBP2 standard.  Set if data is to be written by the device into the host's memory.</p>
353		<p>kFWSBP2CommandImmediate - Immediate Append.  ORB address will be written to fetch agent and not chained.  It is only legal to have one immediate ORB in progress at a time.</p>
354		<p>kFWSBP2CommandNormalORB - ORB format 0 - Format specified by SBP2 standard.  Set this for most ORBs.</p>
355		<p>kFWSBP2CommandReservedORB - ORB format 1 - Format reserved by SBP2 standard for future standardization.</p>
356		<p>kFWSBP2CommandVendorORB - ORB format 2 - Format specified by SBP2 standard for vendor dependent ORBs.</p>
357		<p>kFWSBP2CommandDummyORB - ORB format 3 - Format specified by SBP2 standard for dummy ORBs.</p>
358		<p>kFWSBP2CommandCheckGeneration - If set upon submitORB, the ORB will only be appended if generation set with setCommandGeneration() matches the current generation.  Pretty much all SBP2 drivers need sophisticated logic to track login state, so this is generally not used. </p>
359		<p>kFWSBP2CommandFixedSize - Do not allocate more memory for page table if needed.  If there is not enough space in the currently allocated page table, the setCommandBuffers call will fail.  This is important to set if your device is the backing store, as we don't want to cause memory allocations on the paging path. </p>
360		<p>kFWSBP2CommandVirtualORBs - Normally ORBs are backed by physical address spaces.  Setting this flag makes this ORB backed by a pseudo address space.  This can make ORBs easier to see in a bus trace.  Virtual ORBs will have an address in the form of ffcX.XXXX.0000.0000.  Pseudo address space backed ORBs are slower, so you won't want to set for deployment builds.</p>
361        @param flags The flags to be set.
362    */
363
364    virtual void setCommandFlags( UInt32 flags );
365
366    /*!
367        @function getCommandFlags
368        @abstract Sets configuration flags for the ORB.
369        @discussion Returns the current configuration flags set on this ORB.
370        @result Return The current ORB flags.
371    */
372
373    virtual UInt32 getCommandFlags( void );
374
375    /*!
376        @function setMaxPayloadSize
377        @abstract Sets max payload size for the ORB.
378        @discussion This sets the maximum payload size for this ORB only.  This size is clipped by
379        the global max payload size set in the login object.
380        @param maxPayloadSize The maximum payload size in bytes.
381    */
382
383    virtual void setMaxPayloadSize( UInt32 maxPayloadSize );
384
385    /*!
386        @function getMaxPayloadSize
387        @abstract Gets max payload size for the ORB.
388        @discussion This gets the maximum payload size for this ORB only.
389        @result Returns the maximum payload size in bytes.
390    */
391
392    virtual UInt32 getMaxPayloadSize( void );
393
394    /*!
395        @function setCommandTimeout
396        @abstract Sets the timeout of the ORB.
397        @discussion This sets the timeout for the ORB in milliseconds. Note that ORBs without timeouts
398        can be "lost."  You will obviously not recieve timeout notification for timeouts of zero.  But
399        perhaps less obviously you will not recieve orb reset notification, which is really a sort of
400        accelerated timeout notification for bus reset situations.
401        @param timeout The timeout duration in milliseconds.
402    */
403
404    virtual void setCommandTimeout( UInt32 timeout );
405
406    /*!
407        @function getCommandTimeout
408        @abstract Gets the timeout of the ORB.
409        @discussion This method gets the timeout for this ORB in milliseconds.
410        @result Returns the timeout for the orb in milliseconds.
411    */
412
413    virtual UInt32 getCommandTimeout( void );
414
415
416    /*!
417        @function setCommandGeneration
418        @abstract Sets the command generation.
419        @discussion This sets the bus generation this ORB should be appended in.  It is only meaningful
420        when combined with the kFWSBP2CommandCheckGeneration flags above.
421        @param gen The bus generation for command execution.
422    */
423
424    virtual void setCommandGeneration( UInt32 gen );
425
426    /*!
427        @function getCommandGeneration
428        @abstract Gets the command generation.
429        @discussion This gets the bus generation this ORB should be appended in.
430        @result Returns the bus generation for command execution.
431    */
432
433    virtual UInt32 getCommandGeneration( void );
434
435    /*!
436		@function setRefCon
437		@abstract Sets the ORB refCon.
438		@discussion Sets a user defined value on the ORB that can be retrieved later with the
439        method getRefCon.
440        @param refCon a user defined value.
441    */
442
443    virtual void setRefCon( void * refCon );
444
445    /*!
446		@function getRefCon
447		@abstract Returns the refCon set with setRefCon.
448		@discussion Returns the user defined value previously stored in the ORB with setRefCon.
449        @result Returns the previously stored user defined value.
450	*/
451
452    virtual void * getRefCon( void );
453
454protected:
455
456    virtual void setToDummy( void );
457
458public:
459    /*!
460		@function getORBAddress
461		@abstract Returns the FireWire address of this ORB.
462		@discussion Returns the FireWire bus address of this ORB.  This is not the same as the Macintosh
463        address for the IOFireWireSBP2ORB.
464        @result Returns the FireWire address of this ORB.
465	*/
466
467    virtual void getORBAddress( FWAddress * address );
468
469protected:
470
471	virtual bool isAppended( void );
472	virtual void setIsAppended( bool state );
473	virtual UInt32 getFetchAgentWriteRetries( void );
474    virtual void setFetchAgentWriteRetries( UInt32 retries );
475
476    virtual void prepareFastStartPacket( IOBufferMemoryDescriptor * descriptor );
477
478	UInt32 getFetchAgentWriteRetryInterval( void );
479    void setFetchAgentWriteRetryInterval( UInt32 interval );
480
481	IOReturn completeBufferAddressSpace( void );
482	IOReturn prepareBufferAddressSpace( IOMemoryDescriptor * memoryDescriptor );
483
484public:
485
486    /*!
487		@function setBufferConstraints
488		@abstract Configures page table generation parameters
489		@discussion Sets the maximums size of any page table segment and the required alignemnt.  Double buffering
490		may be used to satisfy these constraints. The only supported option is kFWSBP2ConstraintForceDoubleBuffer which
491		forces a page aligned double buffering of the entire descriptor.
492        @result May return an error if there is a problem allocating the underlying resources or if buffers are currently attached.
493	*/
494
495	IOReturn setBufferConstraints( UInt64 maxSegmentSize, UInt32 alignment, UInt32 options = 0);
496
497
498    /*!
499        @function setCommandBuffersAsRanges64
500        @abstract Creates a page table from a list of 64 bit ranges.
501        @discussion Creates a page table with the given parameters. Any addresses mapped by this method
502        must remain valid until setCommandBuffers is called again or releaseCommandBuffers is called.
503        The SBP2 services do not release references to the command buffers just because the command
504        has completed. This is a 64 bit compatible version of setCommandBuffersAsRanges.
505        @param ranges An array of ranges representing the data to be transfered.
506        @param withCount The number of ranges in the ranges array.
507        @param withDirection An IODirection indicating the direction of data transfer.
508        @param withTask The task that these adressses reside in.
509        @param offset Offset in bytes into data to begin writing table at.
510        @param length Number of bytes of data to map from offset.
511        @result Returns KIOReturnSuccess if the page table was written successfully.
512    */
513
514    IOReturn setCommandBuffersAsRanges64(	IOAddressRange *	ranges,
515											uint64_t			withCount,
516											IODirection			withDirection,
517											task_t				withTask,
518											uint64_t			offset = 0,
519											uint64_t			length = 0);
520
521    /*!
522		@function setRefCon64
523		@abstract Sets the ORB refCon as a 64 bit value.
524		@discussion Sets a user defined value on the ORB that can be retrieved later with the
525        method getRefCon.
526        @param refCon a user defined value.
527    */
528
529    virtual void setRefCon64( UInt64 refCon );
530
531    /*!
532		@function getRefCon64
533		@abstract Returns the 64 bit refCon set with setRefCon64.
534		@discussion Returns the user defined value previously stored in the ORB with setRefCon.
535        @result Returns the previously stored user defined value.
536	*/
537
538    virtual UInt64 getRefCon64( void );
539
540protected:
541
542	UInt32	calculateTransferSizeLog( bool * clipping );
543
544
545};
546
547#endif
548