xref: /xnu-8792.61.2/iokit/IOKit/IODMACommand.h (revision 42e220869062b56f8d7d0726fd4c88954f87902c)
1 /*
2  * Copyright (c) 2005-2016 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #ifndef _IODMACOMMAND_H
29 #define _IODMACOMMAND_H
30 
31 #include <IOKit/IOCommand.h>
32 #include <IOKit/IOMemoryDescriptor.h>
33 #include <DriverKit/IODMACommand.h>
34 class IOMapper;
35 class IOBufferMemoryDescriptor;
36 
37 enum{
38 	kIODMAMapOptionMapped       = 0x00000000,
39 	kIODMAMapOptionBypassed     = 0x00000001,
40 	kIODMAMapOptionNonCoherent  = 0x00000002,
41 	kIODMAMapOptionUnmapped     = 0x00000003,
42 	kIODMAMapOptionTypeMask     = 0x0000000f,
43 
44 	kIODMAMapOptionNoCacheStore = 0x00000010, // Memory in descriptor
45 	kIODMAMapOptionOnChip       = 0x00000020, // Indicates DMA is on South Bridge
46 	kIODMAMapOptionIterateOnly  = 0x00000040, // DMACommand will be used as a cursor only
47 	kIODMAMapOptionDextOwner    = 0x00000080  // Dext owned
48 };
49 
50 /**************************** class IODMACommand ***************************/
51 
52 /*!
53  *   @class IODMACommand
54  *   @abstract A mechanism to convert memory references to I/O bus addresses.
55  *   @discussion The IODMACommand is supersedes the IOMemoryCursor and greatly enhances the functionality and power of it.  The command can be specified to output 64 bit physical addresses and also allows driver writers bypass mapping hardware or get addresses suitable for non-snooped DMA.
56  *  <br><br>
57  *   The command is designed to be very easily subclassable.  Most driver writers need to associate some DMA operations with their memory descriptor and usually use a C structure for that purpose.  This structure is often kept in a linked list.  This IODMACommand has built it <kern/queue.h> linkage and can be derived and 'public:' variables added, giving the developer a structure that can associate a memory descriptor with a particular dma command but will also allow the developer to generate that command and keep the state necessary for tracking it.
58  *  <br><br>
59  *   It is envisaged that a pool of IODMACommands will be created at driver initialisation and each command will be kept in an IOCommandPool while not in use.  However if developers wishes to maintain their own free lists that is certainly possible.  See the <kern/queue.h> and <xnu/iokit/Kernel/IOCommandPool> for sample code on manipulating the command's doubly linked list entries.
60  *  <br><br>
61  *   The IODMACommand can be used in a 'weak-linked' manner.  To do this you must avoid using any static member functions.  Use the, much slower but safe, weakWithSpecification function.  On success a dma command instance will be returned.  This instance can then be used to clone as many commands as is needed.  Remember deriving from this class can not be done weakly, that is no weak subclassing!
62  */
63 
64 class IODMACommand : public IOCommand
65 {
66 	OSDeclareDefaultStructorsWithDispatch(IODMACommand);
67 
68 	friend class IODMAEventSource;
69 
70 public:
71 
72 /*!
73  *   @typedef Segment32
74  *   @discussion A 32 bit I/O bus address/length pair
75  */
76 	struct Segment32 {
77 		UInt32 fIOVMAddr, fLength;
78 	};
79 
80 /*!
81  *   @typedef Segment64
82  *   @discussion A 64 bit I/O bus address/length pair
83  */
84 	struct Segment64 {
85 		UInt64 fIOVMAddr, fLength;
86 	};
87 
88 /*! @enum MappingOptions
89  *   @abstract Mapping types to indicate the desired mapper type for translating memory descriptors into I/O DMA Bus addresses.
90  *   @constant kNonCoherent	Used by drivers for non-coherent transfers, implies unmapped memmory
91  *   @constant kMapped		Allow a driver to define addressing size
92  *   @constant kBypassed		Allow drivers to bypass any mapper
93  *   @constant kMaxMappingOptions	Internal use only
94  */
95 	enum MappingOptions {
96 		kMapped       = kIODMAMapOptionMapped,
97 		kBypassed     = kIODMAMapOptionBypassed,
98 		kNonCoherent  = kIODMAMapOptionNonCoherent,
99 		kUnmapped     = kIODMAMapOptionUnmapped,
100 		kTypeMask     = kIODMAMapOptionTypeMask,
101 
102 		kNoCacheStore = kIODMAMapOptionNoCacheStore, // Memory in descriptor
103 		kOnChip       = kIODMAMapOptionOnChip,  // Indicates DMA is on South Bridge
104 		kIterateOnly  = kIODMAMapOptionIterateOnly// DMACommand will be used as a cursor only
105 	};
106 
107 	struct SegmentOptions {
108 		uint8_t  fStructSize;
109 		uint8_t  fNumAddressBits;
110 		uint64_t fMaxSegmentSize;
111 		uint64_t fMaxTransferSize;
112 		uint32_t fAlignment;
113 		uint32_t fAlignmentLength;
114 		uint32_t fAlignmentInternalSegments;
115 	};
116 
117 /*! @enum SynchronizeOptions
118  *   @abstract Options for the synchronize method.
119  *   @constant kForceDoubleBuffer Copy the entire prepared range to a new page aligned buffer.
120  */
121 	enum SynchronizeOptions {
122 		kForceDoubleBuffer = 0x01000000
123 	};
124 
125 /*!
126  *   @typedef SegmentFunction
127  *   @discussion Pointer to a C function that translates a 64 segment and outputs a single desired segment to the array at the requested index. There are a group of pre-implemented SegmentFunctions that may be usefull to the developer below.
128  *   @param segment The 64Bit I/O bus address and length.
129  *   @param segments Base of the output vector of DMA address length pairs.
130  *   @param segmentIndex Index to output 'segment' in the 'segments' array.
131  *   @result Returns true if segment encoding succeeded.  false may be returned if the current segment does not fit in an output segment, i.e. a 38bit address wont fit into a 32 encoding.
132  */
133 	typedef bool (*SegmentFunction)(IODMACommand *target,
134 	    Segment64 segment,
135 	    void     *segments,
136 	    UInt32    segmentIndex);
137 
138 // -------------- Preimplemented output functions ----------------
139 
140 /*! @function OutputHost32
141  *   @abstract Output host natural Segment32 output segment function.
142  */
143 	static bool OutputHost32(IODMACommand *target,
144 	    Segment64 seg, void *segs, UInt32 ind);
145 
146 /*! @defined kIODMACommandOutputHost32
147  *   @abstract Output host natural Segment32 output segment function.
148  */
149 #define kIODMACommandOutputHost32   (IODMACommand::OutputHost32)
150 
151 /*! @function OutputBig32
152  *   @abstract Output big-endian Segment32 output segment function.
153  */
154 	static bool OutputBig32(IODMACommand *target,
155 	    Segment64 seg, void *segs, UInt32 ind);
156 
157 /*! @defined kIODMACommandOutputBig32
158  *   @abstract Output big-endian Segment32 output segment function.
159  */
160 #define kIODMACommandOutputBig32    (IODMACommand::OutputBig32)
161 
162 /*! @function OutputLittle32
163  *   @abstract Output little-endian Segment32 output segment function.
164  */
165 	static bool OutputLittle32(IODMACommand *target,
166 	    Segment64 seg, void *segs, UInt32 ind);
167 
168 /*! @defined kIODMACommandOutputLittle32
169  *   @abstract Output little-endian Segment32 output segment function.
170  */
171 #define kIODMACommandOutputLittle32 (IODMACommand::OutputLittle32)
172 
173 /*! @function OutputHost64
174  *   @abstract Output host natural Segment64 output segment function.
175  */
176 	static bool OutputHost64(IODMACommand *target,
177 	    Segment64 seg, void *segs, UInt32 ind);
178 
179 /*! @defined kIODMACommandOutputHost64
180  *   @abstract Output host natural Segment64 output segment function.
181  */
182 #define kIODMACommandOutputHost64   (IODMACommand::OutputHost64)
183 
184 /*! @function OutputBig64
185  *   @abstract Output big-endian Segment64 output segment function.
186  */
187 	static bool OutputBig64(IODMACommand *target,
188 	    Segment64 seg, void *segs, UInt32 ind);
189 
190 /*! @defined kIODMACommandOutputBig64
191  *   @abstract Output big-endian Segment64 output segment function.
192  */
193 #define kIODMACommandOutputBig64    (IODMACommand::OutputBig64)
194 
195 /*! @function OutputLittle64
196  *   @abstract Output little-endian Segment64 output segment function.
197  */
198 	static bool OutputLittle64(IODMACommand *target,
199 	    Segment64 seg, void *segs, UInt32 ind);
200 
201 /*! @defined kIODMACommandOutputLittle64
202  *   @abstract Output little-endian Segment64 output segment function.
203  */
204 #define kIODMACommandOutputLittle64 (IODMACommand::OutputLittle64)
205 
206 /*! @function withSpecification
207  *   @abstract Creates and initializes an IODMACommand in one operation.
208  *   @discussion Factory function to create and initialize an IODMACommand in one operation.
209  *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
210  *   @param numAddressBits Number of bits that the hardware uses on its internal address bus. Typically 32 but may be more on modern hardware.  A 0 implies no-restriction other than that implied by the output segment function.
211  *   @param maxSegmentSize Maximum allowable size for one segment.  If 0 is passed the maximum segment size is unlimited.
212  *   @param mappingOptions is the type of mapping that is required to translate an IOMemoryDescriptor into the desired number of bits.  For instance if your hardware only supports 32 bits but must run on machines with > 4G of RAM some mapping will be required.  Number of bits will be specified in numAddressBits, see below.This parameter can take 3 values:- kNonCoherent - used for non-coherent hardware transfers, Mapped - Validate that all I/O bus generated addresses are within the number of addressing bits specified, Bypassed indicates that bypassed addressing is required, this is used when the hardware transferes are into coherent memory but no mapping is required.  See also prepare() for failure cases.
213  *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
214  *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
215  *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
216  *   @param refCon Reference Constant
217  *   @result Returns a new IODMACommand if successfully created and initialized, 0 otherwise.
218  */
219 	static OSPtr<IODMACommand>
220 	withSpecification(SegmentFunction  outSegFunc,
221 	    UInt8            numAddressBits,
222 	    UInt64           maxSegmentSize,
223 	    MappingOptions   mappingOptions = kMapped,
224 	    UInt64           maxTransferSize = 0,
225 	    UInt32           alignment = 1,
226 	    IOMapper        *mapper = NULL,
227 	    void            *refCon = NULL);
228 
229 /*! @function weakWithSpecification
230  *   @abstract Creates and initialises an IODMACommand in one operation if this version of the operating system supports it.
231  *   @discussion Factory function to create and initialise an IODMACommand in one operation.  The function allows a developer to 'weak' link with IODMACommand.  This function will return kIOReturnUnsupported if the IODMACommand is unavailable.  This function is actually fairly slow so it will be better to call it once then clone the successfully create command using cloneCommand (q.v.).
232  *   @param newCommand Output reference variable of the newly created IODMACommand.
233  *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
234  *   @param numAddressBits Number of bits that the hardware uses on its internal address bus. Typically 32 but may be more on modern hardware.  A 0 implies no-restriction other than that implied by the output segment function.
235  *   @param maxSegmentSize Maximum allowable size for one segment. Zero is treated as an unlimited segment size.
236  *   @param mapType is the type of mapping that is required to translate an IOMemoryDescriptor into the desired number of bits.  For instance if your hardware only supports 32 bits but must run on machines with > 4G of RAM some mapping will be required.  Number of bits will be specified in numAddressBits, see below.  This parameter can take 3 values:- kNonCoherent - used for non-coherent hardware transfers, Mapped - Validate that all I/O bus generated addresses are within the number of addressing bits specified, Bypassed indicates that bypassed addressing is required, this is used when the hardware transfers are into coherent memory but no mapping is required.  See also prepare() for failure cases.
237  *   @param maxTransferSize Maximum size of an entire transfer.  Defaults to 0 indicating no maximum.
238  *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
239  *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
240  *   @param refCon Reference Constant
241  *   @result kIOReturnSuccess if everything is OK, otherwise kIOReturnBadArgument if newCommand is NULL, kIOReturnUnsupported if the kernel doesn't export IODMACommand or IOReturnError if the new command fails to init, q.v. initWithSpecification.
242  */
243 // Note that the function has the attribute always_inline.
244 // The point of this function is to make a call into the kernel
245 // without generating an undefined symbol.  If the client could call
246 // the code as a function then the goal of no undefined symbols
247 // would be lost thus defeating the purpose.
248 	static inline IOReturn weakWithSpecification
249 	(IODMACommand   **newCommand,
250 	    SegmentFunction outSegFunc,
251 	    UInt8           numAddressBits,
252 	    UInt64          maxSegmentSize,
253 	    MappingOptions  mapType = kMapped,
254 	    UInt64          maxTransferSize = 0,
255 	    UInt32          alignment = 1,
256 	    IOMapper       *mapper = NULL,
257 	    void           *refCon = NULL) __attribute__((always_inline));
258 
259 	static OSPtr<IODMACommand>
260 	withSpecification(SegmentFunction        outSegFunc,
261 	    const SegmentOptions * segmentOptions,
262 	    uint32_t               mappingOptions,
263 	    IOMapper             * mapper,
264 	    void                 * refCon);
265 
266 
267 /*! @function withRefCon
268  *   @abstract Creates and initializes an unspecified IODMACommand.
269  *   @discussion Factory function to create and initialize an unspecified IODMACommand. prepareWithSpecification() must be used to prepare the IODMACommand before use.
270  *   @param refCon Reference Constant
271  *   @result Returns a new IODMACommand if successfully created and initialized, 0 otherwise.
272  */
273 	static OSPtr<IODMACommand> withRefCon(void * refCon);
274 
275 /*!
276  *   @function cloneCommand
277  *   @abstract Creates a new command based on the specification of the current one.
278  *   @discussion Factory function to create and initialise an IODMACommand in one operation.  The current command's specification will be duplicated in the new object, but however none of its state will be duplicated.  This means that it is safe to clone a command even if it is currently active and running, however you must be certain that the command to be duplicated does have a valid reference for the duration.
279  *   @result Returns a new IODMACommand if successfully created and initialised, 0 otherwise.
280  */
281 	virtual OSPtr<IODMACommand> cloneCommand(void *refCon = NULL);
282 
283 /*! @function initWithSpecification
284  *   @abstract Primary initializer for the IODMACommand class.
285  *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
286  *   @param numAddressBits Number of bits that the hardware uses on its internal address bus. Typically 32 but may be more on modern hardware.  A 0 implies no-restriction other than that implied by the output segment function.
287  *   @param maxSegmentSize Maximum allowable size for one segment.  Defaults to 0 which means any size.
288  *   @param mappingOptions is the type of mapping that is required to translate an IOMemoryDescriptor into the desired number of bits.  For instance if your hardware only supports 32 bits but must run on machines with > 4G of RAM some mapping will be required.  Number of bits will be specified in numAddressBits, see below.This parameter can take 3 values:- kNonCoherent - used for non-coherent hardware transfers, Mapped - Validate that all I/O bus generated addresses are within the number of addressing bits specified, Bypassed indicates that bypassed addressing is required, this is used when the hardware transferes are into coherent memory but no mapping is required.  See also prepare() for failure cases.
289  *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
290  *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
291  *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
292  *   @param refCon Reference Constant
293  *   @result Can fail if the mapping type is not recognised, if one of the 3 mandatory parameters are set to 0, if a 32 bit output function is selected when more than 32 bits of address is required or, if kBypassed is requested on a machine that doesn't support bypassing.  Returns true otherwise.
294  */
295 	virtual bool initWithSpecification( SegmentFunction  outSegFunc,
296 	    UInt8     numAddressBits,
297 	    UInt64    maxSegmentSize,
298 	    MappingOptions mappingOptions = kMapped,
299 	    UInt64    maxTransferSize = 0,
300 	    UInt32    alignment = 1,
301 	    IOMapper *mapper = NULL,
302 	    void     *refCon = NULL);
303 
304 /*! @function setMemoryDescriptor
305  *   @abstract Sets and resets the DMACommand's current memory descriptor
306  *   @discussion The DMA command will configure itself based on the information that it finds in the memory descriptor.  It looks for things like the direction of the memory descriptor and whether the current memory descriptor is already mapped into some IOMMU.  As a programmer convenience it can also prepare the DMA command immediately.  See prepare().  Note the IODMACommand is designed to used multiple times with a succession of memory descriptors, making the pooling of commands possible.  It is an error though to attempt to reset a currently prepared() DMA command.  Warning: This routine may block so never try to autoprepare an IODMACommand while in a gated context, i.e. one of the WorkLoops action call outs.
307  *   @param mem A pointer to the current I/Os memory descriptor.
308  *   @param autoPrepare An optional boolean variable that will call the prepare() function automatically after the memory descriptor is processed. Defaults to true.
309  *   @result Returns kIOReturnSuccess, kIOReturnBusy if currently prepared, kIOReturnNoSpace if the length(mem) >= Maximum Transfer Size, kIOReturnCannotLock if called from the interrupt context or with a spinlock held, or the error codes returned by prepare() (qv).
310  */
311 	virtual IOReturn setMemoryDescriptor(const IOMemoryDescriptor *mem,
312 	    bool autoPrepare = true);
313 
314 /*! @function clearMemoryDescriptor
315  *   @abstract Clears the DMACommand's current memory descriptor
316  *   @discussion completes and invalidates the cache if the DMA command is currently active, copies all data from bounce buffers if necessary and releases all resources acquired during setMemoryDescriptor.
317  *   @param autoComplete An optional boolean variable that will call the complete() function automatically before the memory descriptor is processed. Defaults to true.
318  */
319 	virtual IOReturn clearMemoryDescriptor(bool autoComplete = true);
320 
321 /*! @function getMemoryDescriptor
322  *   @abstract Get the current memory descriptor
323  */
324 	virtual const IOMemoryDescriptor * getMemoryDescriptor() const;
325 
326 /*! @function getIOMemoryDescriptor
327  *   @abstract Get the memory descriptor to be used for DMA
328  */
329 	IOMemoryDescriptor * getIOMemoryDescriptor() const;
330 
331 /*! @function prepare
332  *   @abstract Prepare the memory for an I/O transfer.
333  *   @discussion Allocate the mapping resources neccessary for this transfer, specifying a sub range of the IOMemoryDescriptor that will be the target of the I/O.  The complete() method frees these resources.  Data may be copied to buffers for kIODirectionOut memory descriptors, depending on hardware mapping resource availabilty or alignment restrictions.  It should be noted that the this function may block and should only be called on the clients context, i.e never call this routine while gated; also the call itself is not thread safe though this should be an issue as each IODMACommand is independant.
334  *   @param offset defines the starting offset in the memory descriptor the DMA command will operate on. genIOVMSegments will produce its results based on the offset and length passed to the prepare method.
335  *   @param length defines the ending position in the memory descriptor the DMA command will operate on. genIOVMSegments will produce its results based on the offset and length passed to the prepare method.
336  *   @param flushCache Flush the caches for the memory descriptor and make certain that the memory cycles are complete.  Defaults to true for kNonCoherent and is ignored by the other types.
337  *   @param synchronize Copy any buffered data back from the target IOMemoryDescriptor.  Defaults to true, if synchronize() is being used to explicitly copy data, passing false may avoid an unneeded copy.
338  *   @result An IOReturn code. */
339 
340 	virtual IOReturn prepare(UInt64 offset = 0, UInt64 length = 0, bool flushCache = true, bool synchronize = true);
341 
342 /*! @function complete
343  *   @abstract Complete processing of DMA mappings after an I/O transfer is finished.
344  *   @discussion This method should not be called unless a prepare was previously issued; the prepare() and complete() must occur in pairs, before and after an I/O transfer
345  *   @param invalidateCache Invalidate the caches for the memory descriptor.  Defaults to true for kNonCoherent and is ignored by the other types.
346  *   @param synchronize Copy any buffered data back to the target IOMemoryDescriptor.  Defaults to true, if synchronize() is being used to explicitly copy data, passing false may avoid an unneeded copy.
347  *   @result kIOReturnNotReady if not prepared, kIOReturnSuccess otherwise. */
348 
349 	virtual IOReturn complete(bool invalidateCache = true, bool synchronize = true);
350 
351 /*! @function synchronize
352  *   @abstract Bring IOMemoryDescriptor and IODMACommand buffers into sync.
353  *   @discussion This method should not be called unless a prepare was previously issued. If needed a caller may synchronize any IODMACommand buffers with the original IOMemoryDescriptor buffers.
354  *   @param options Specifies the direction of the copy:
355  *       kIODirectionOut copy IOMemoryDesciptor memory to any IODMACommand buffers. By default this action takes place automatically at prepare().
356  *       kIODirectionIn copy any IODMACommand buffers back to the IOMemoryDescriptor. By default this action takes place automatically at complete().
357  *       kForceDoubleBuffer copy the entire prepared range to a new page aligned buffer.
358  *   @result kIOReturnNotReady if not prepared, kIOReturnBadArgument if invalid options are passed, kIOReturnSuccess otherwise. */
359 
360 	virtual IOReturn synchronize(IOOptionBits options);
361 
362 /*! @function genIOVMSegments
363  *   @abstract Generates a physical scatter/gather for the current DMA command
364  *   @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor.  The constraints that are set during initialisation will be respected. This function maintains the state across multiple calls for efficiency.  However the state is discarded if the new offset is not the expected one.
365  *   @param offset input/output parameter, defines the starting and ending offset in the memory descriptor, relative to any offset passed to the prepare() method.
366  *   @param segments Void pointer to base of output physical scatter/gather list.  Always passed directly onto the SegmentFunction.
367  *   @param numSegments Input/output parameter Number of segments that can fit in the segment array and returns number of segments generated.
368  *   @result kIOReturnSuccess on success, kIOReturnOverrun if the memory descriptor is exhausted, kIOReturnMessageTooLarge if the output segment function's address bits has insufficient resolution for a segment, kIOReturnNotReady if the DMA command has not be prepared, kIOReturnBadArgument if the DMA command doesn't have a memory descriptor yet or some of the parameters are NULL and kIOReturnNotReady if the DMA command is not prepared.
369  */
370 	virtual IOReturn genIOVMSegments(UInt64 *offset,
371 	    void   *segments,
372 	    UInt32 *numSegments);
373 
374 private:
375 	virtual UInt64 transfer( IOOptionBits transferOp, UInt64 offset, void * buffer, UInt64 length );
376 
377 public:
378 
379 /*! @function writeBytes
380  *   @abstract Copy data to the IODMACommand's buffer from the specified buffer.
381  *   @discussion This method copies data to the IODMACommand's memory at the given offset, from the caller's buffer. The IODMACommand must be prepared, and the offset is relative to the prepared offset.
382  *   @param offset A byte offset into the IODMACommand's memory, relative to the prepared offset.
383  *   @param bytes The caller supplied buffer to copy the data from.
384  *   @param length The length of the data to copy.
385  *   @result The number of bytes copied, zero will be returned if the specified offset is beyond the prepared length of the IODMACommand. */
386 
387 	UInt64 writeBytes(UInt64 offset, const void *bytes, UInt64 length);
388 
389 /*! @function readBytes
390  *   @abstract Copy data from the IODMACommand's buffer to the specified buffer.
391  *   @discussion This method copies data from the IODMACommand's memory at the given offset, to the caller's buffer. The IODMACommand must be prepared, and the offset is relative to the prepared offset.
392  *   @param offset A byte offset into the IODMACommand's memory, relative to the prepared offset.
393  *   @param bytes The caller supplied buffer to copy the data to.
394  *   @param length The length of the data to copy.
395  *   @result The number of bytes copied, zero will be returned if the specified offset is beyond the prepared length of the IODMACommand. */
396 
397 	UInt64 readBytes(UInt64 offset, void *bytes, UInt64 length);
398 
399 /*! @function gen32IOVMSegments
400  *   @abstract Helper function for a type checked call to genIOVMSegments(qv), for use with an IODMACommand set up with the output function kIODMACommandOutputHost32, kIODMACommandOutputBig32, or kIODMACommandOutputLittle32. If the output function of the IODMACommand is not a 32 bit function, results will be incorrect.
401  */
402 	inline IOReturn
gen32IOVMSegments(UInt64 * offset,Segment32 * segments,UInt32 * numSegments)403 	gen32IOVMSegments(UInt64   *offset,
404 	    Segment32 *segments,
405 	    UInt32     *numSegments)
406 	{
407 		return genIOVMSegments(offset, segments, numSegments);
408 	}
409 
410 /*! @function gen64IOVMSegments
411  *   @abstract Helper function for a type checked call to genIOVMSegments(qv), for use with an IODMACommand set up with the output function kIODMACommandOutputHost64, kIODMACommandOutputBig64, or kIODMACommandOutputLittle64. If the output function of the IODMACommand is not a 64 bit function, results will be incorrect.
412  */
413 	inline IOReturn
gen64IOVMSegments(UInt64 * offset,Segment64 * segments,UInt32 * numSegments)414 	gen64IOVMSegments(UInt64    *offset,
415 	    Segment64 *segments,
416 	    UInt32    *numSegments)
417 	{
418 		return genIOVMSegments(offset, segments, numSegments);
419 	}
420 
421 	IOReturn
422 	genIOVMSegments(SegmentFunction segmentFunction,
423 	    UInt64 *offsetP,
424 	    void   *segmentsP,
425 	    UInt32 *numSegmentsP);
426 
427 	virtual void free() APPLE_KEXT_OVERRIDE;
428 
429 private:
430 	IOReturn setSpecification(SegmentFunction        outSegFunc,
431 	    const SegmentOptions * segmentOptions,
432 	    uint32_t               mappingOptions,
433 	    IOMapper             * mapper);
434 
435 	typedef IOReturn (*InternalSegmentFunction)(
436 		void         *reference,
437 		IODMACommand *target,
438 		Segment64     segment,
439 		void         *segments,
440 		UInt32        segmentIndex);
441 
442 	IOReturn genIOVMSegments(uint32_t op,
443 	    InternalSegmentFunction outSegFunc,
444 	    void   *reference,
445 	    UInt64 *offsetP,
446 	    void   *segmentsP,
447 	    UInt32 *numSegmentsP);
448 
449 	static IOReturn clientOutputSegment(
450 		void *reference, IODMACommand *target,
451 		Segment64 segment, void *vSegList, UInt32 outSegIndex);
452 
453 	static IOReturn segmentOp(
454 		void         *reference,
455 		IODMACommand *target,
456 		Segment64     segment,
457 		void         *segments,
458 		UInt32        segmentIndex);
459 	IOReturn walkAll(uint32_t op);
460 
461 public:
462 
463 /*! @function prepareWithSpecification
464  *   @abstract Prepare the memory for an I/O transfer with a new specification.
465  *   @discussion Allocate the mapping resources neccessary for this transfer, specifying a sub range of the IOMemoryDescriptor that will be the target of the I/O.  The complete() method frees these resources.  Data may be copied to buffers for kIODirectionOut memory descriptors, depending on hardware mapping resource availabilty or alignment restrictions.  It should be noted that the this function may block and should only be called on the clients context, i.e never call this routine while gated; also the call itself is not thread safe though this should be an issue as each IODMACommand is independant.
466  *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
467  *   @param numAddressBits Number of bits that the hardware uses on its internal address bus. Typically 32 but may be more on modern hardware.  A 0 implies no-restriction other than that implied by the output segment function.
468  *   @param maxSegmentSize Maximum allowable size for one segment.  Defaults to 0 which means any size.
469  *   @param mappingOptions is the type of mapping that is required to translate an IOMemoryDescriptor into the desired number of bits.  For instance if your hardware only supports 32 bits but must run on machines with > 4G of RAM some mapping will be required.  Number of bits will be specified in numAddressBits, see below.This parameter can take 3 values:- kNonCoherent - used for non-coherent hardware transfers, Mapped - Validate that all I/O bus generated addresses are within the number of addressing bits specified, Bypassed indicates that bypassed addressing is required, this is used when the hardware transferes are into coherent memory but no mapping is required.  See also prepare() for failure cases.
470  *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
471  *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
472  *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
473  *   @param offset defines the starting offset in the memory descriptor the DMA command will operate on. genIOVMSegments will produce its results based on the offset and length passed to the prepare method.
474  *   @param length defines the ending position in the memory descriptor the DMA command will operate on. genIOVMSegments will produce its results based on the offset and length passed to the prepare method.
475  *   @param flushCache Flush the caches for the memory descriptor and make certain that the memory cycles are complete.  Defaults to true for kNonCoherent and is ignored by the other types.
476  *   @param synchronize Copy any buffered data back from the target IOMemoryDescriptor.  Defaults to true, if synchronize() is being used to explicitly copy data, passing false may avoid an unneeded copy.
477  *   @result An IOReturn code. Can fail if the mapping type is not recognised, if one of the 3 mandatory parameters are set to 0, if a 32 bit output function is selected when more than 32 bits of address is required or, if kBypassed is requested on a machine that doesn't support bypassing.
478  */
479 
480 	virtual IOReturn prepareWithSpecification(SegmentFunction   outSegFunc,
481 	    UInt8             numAddressBits,
482 	    UInt64            maxSegmentSize,
483 	    MappingOptions    mappingOptions = kMapped,
484 	    UInt64            maxTransferSize = 0,
485 	    UInt32            alignment = 1,
486 	    IOMapper          *mapper = NULL,
487 	    UInt64            offset = 0,
488 	    UInt64            length = 0,
489 	    bool              flushCache = true,
490 	    bool              synchronize = true);
491 
492 	static IOReturn transferSegment(void         *reference,
493 	    IODMACommand *target,
494 	    Segment64     segment,
495 	    void         *segments,
496 	    UInt32        segmentIndex);
497 
498 /*! @function getPreparedOffsetAndLength
499  *   @abstract Returns the offset and length into the target IOMemoryDescriptor of a prepared IODDMACommand.
500  *   @discussion If successfully prepared, returns the offset and length into the IOMemoryDescriptor. Will fail for an unprepared IODMACommand.
501  *   @param offset returns the starting offset in the memory descriptor the DMA command was prepared with. Pass NULL for don't care.
502  *   @param length returns the length in the memory descriptor the DMA command was prepared with. Pass NULL for don't care.
503  *   @result An IOReturn code. kIOReturnNotReady if the IODMACommand is not prepared. */
504 
505 	virtual IOReturn getPreparedOffsetAndLength(UInt64 * offset, UInt64 * length);
506 
507 	UInt8    getNumAddressBits(void);
508 	UInt32   getAlignment(void);
509 	uint32_t getAlignmentLength(void);
510 	uint32_t getAlignmentInternalSegments(void);
511 
512 
513 /*! @function initWithRefCon
514  *   @abstract Secondary initializer for the IODMACommand class.
515  *   @param refCon Reference Constant
516  *   @result Can fail if super init fails.  Returns true otherwise.
517  */
518 
519 	virtual
520 	bool initWithRefCon(void * refCon = NULL);
521 
522 	virtual
523 	bool initWithSpecification(SegmentFunction        outSegFunc,
524 	    const SegmentOptions * segmentOptions,
525 	    uint32_t               mappingOptions,
526 	    IOMapper             * mapper,
527 	    void                 * refCon);
528 
529 	virtual
530 	IOReturn prepareWithSpecification(SegmentFunction        outSegFunc,
531 	    const SegmentOptions * segmentOptions,
532 	    uint32_t               mappingOptions,
533 	    IOMapper             * mapper,
534 	    uint64_t               offset,
535 	    uint64_t               length,
536 	    bool                   flushCache = true,
537 	    bool                   synchronize = true);
538 
539 	virtual
540 	OSPtr<IOBufferMemoryDescriptor> createCopyBuffer(IODirection direction, UInt64 length);
541 
542 private:
543 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 0);
544 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 1);
545 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 2);
546 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 3);
547 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 4);
548 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 5);
549 	OSMetaClassDeclareReservedUsedX86(IODMACommand, 6);
550 	OSMetaClassDeclareReservedUnused(IODMACommand, 7);
551 	OSMetaClassDeclareReservedUnused(IODMACommand, 8);
552 	OSMetaClassDeclareReservedUnused(IODMACommand, 9);
553 	OSMetaClassDeclareReservedUnused(IODMACommand, 10);
554 	OSMetaClassDeclareReservedUnused(IODMACommand, 11);
555 	OSMetaClassDeclareReservedUnused(IODMACommand, 12);
556 	OSMetaClassDeclareReservedUnused(IODMACommand, 13);
557 	OSMetaClassDeclareReservedUnused(IODMACommand, 14);
558 	OSMetaClassDeclareReservedUnused(IODMACommand, 15);
559 
560 public:
561 /*! @var fRefCon Reference Constant, client defined publicly avialable */
562 	void *fRefCon;
563 
564 protected:
565 
566 /*! @var fMaxSegmentSize Maximum size of one segment in a scatter/gather list */
567 	UInt64  fMaxSegmentSize;
568 
569 /*! @var fMaxTransferSize
570  *   Maximum size of a transfer that this memory cursor is allowed to generate */
571 	UInt64  fMaxTransferSize;
572 
573 	UInt32  fAlignMaskLength;
574 	UInt32  fAlignMaskInternalSegments;
575 
576 /*! @var fMapper
577  *   Client defined mapper. */
578 	OSPtr<IOMapper> fMapper;
579 
580 /*! @var fMemory
581  *   memory descriptor for current I/O. */
582 	OSPtr<IOMemoryDescriptor> fMemory;
583 
584 /*! @var fOutSeg The action method called when an event has been delivered */
585 	SegmentFunction fOutSeg;
586 
587 /*! @var fAlignMask
588  *   Alignment restriction mask. */
589 	UInt32  fAlignMask;
590 
591 /*! @var fNumAddressBits
592  *   Number of bits that the hardware can address */
593 	UInt32 fNumAddressBits;
594 
595 /*! @var fNumSegments
596  *   Number of contiguous segments required for the current memory descriptor and desired mapping */
597 	UInt32  fNumSegments;
598 
599 /*! @var fMappingOptions
600  *   What type of I/O virtual address mapping is required for this command */
601 	uint32_t  fMappingOptions;
602 
603 /*! @var fActive
604  *   fActive indicates that this DMA command is currently prepared and ready to go */
605 	UInt32 fActive;
606 
607 /*! @var reserved
608  *   Reserved for future use.  (Internal use only)  */
609 	struct IODMACommandInternal  *reserved;
610 };
611 
612 IOReturn
613 IODMACommand::
weakWithSpecification(IODMACommand ** newCommand,SegmentFunction outSegFunc,UInt8 numAddressBits,UInt64 maxSegmentSize,MappingOptions mapType,UInt64 maxTransferSize,UInt32 alignment,IOMapper * mapper,void * refCon)614 weakWithSpecification(IODMACommand **newCommand,
615     SegmentFunction  outSegFunc,
616     UInt8     numAddressBits,
617     UInt64    maxSegmentSize,
618     MappingOptions mapType,
619     UInt64    maxTransferSize,
620     UInt32    alignment,
621     IOMapper *mapper,
622     void     *refCon)
623 {
624 	if (!newCommand) {
625 		return kIOReturnBadArgument;
626 	}
627 
628 	IODMACommand *self = (IODMACommand *)
629 	    OSMetaClass::allocClassWithName("IODMACommand");
630 	if (!self) {
631 		return kIOReturnUnsupported;
632 	}
633 
634 	IOReturn ret;
635 	bool inited = self->
636 	    initWithSpecification(outSegFunc,
637 	    numAddressBits, maxSegmentSize, mapType,
638 	    maxTransferSize, alignment, mapper, refCon);
639 	if (inited) {
640 		ret =  kIOReturnSuccess;
641 	} else {
642 		self->release();
643 		self = NULL;
644 		ret = kIOReturnError;
645 	}
646 
647 	*newCommand = self;
648 	return ret;
649 };
650 #endif /* !_IODMACOMMAND_H */
651