/ duct-tape / xnu / iokit / IOKit / IODMACommand.h
IODMACommand.h
  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  };
 48  
 49  /**************************** class IODMACommand ***************************/
 50  
 51  /*!
 52   *   @class IODMACommand
 53   *   @abstract A mechanism to convert memory references to I/O bus addresses.
 54   *   @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.
 55   *  <br><br>
 56   *   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.
 57   *  <br><br>
 58   *   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.
 59   *  <br><br>
 60   *   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!
 61   */
 62  
 63  class IODMACommand : public IOCommand
 64  {
 65  	OSDeclareDefaultStructorsWithDispatch(IODMACommand);
 66  
 67  	friend class IODMAEventSource;
 68  
 69  public:
 70  
 71  /*!
 72   *   @typedef Segment32
 73   *   @discussion A 32 bit I/O bus address/length pair
 74   */
 75  	struct Segment32 {
 76  		UInt32 fIOVMAddr, fLength;
 77  	};
 78  
 79  /*!
 80   *   @typedef Segment64
 81   *   @discussion A 64 bit I/O bus address/length pair
 82   */
 83  	struct Segment64 {
 84  		UInt64 fIOVMAddr, fLength;
 85  	};
 86  
 87  /*! @enum MappingOptions
 88   *   @abstract Mapping types to indicate the desired mapper type for translating memory descriptors into I/O DMA Bus addresses.
 89   *   @constant kNonCoherent	Used by drivers for non-coherent transfers, implies unmapped memmory
 90   *   @constant kMapped		Allow a driver to define addressing size
 91   *   @constant kBypassed		Allow drivers to bypass any mapper
 92   *   @constant kMaxMappingOptions	Internal use only
 93   */
 94  	enum MappingOptions {
 95  		kMapped       = kIODMAMapOptionMapped,
 96  		kBypassed     = kIODMAMapOptionBypassed,
 97  		kNonCoherent  = kIODMAMapOptionNonCoherent,
 98  		kUnmapped     = kIODMAMapOptionUnmapped,
 99  		kTypeMask     = kIODMAMapOptionTypeMask,
100  
101  		kNoCacheStore = kIODMAMapOptionNoCacheStore, // Memory in descriptor
102  		kOnChip       = kIODMAMapOptionOnChip,  // Indicates DMA is on South Bridge
103  		kIterateOnly  = kIODMAMapOptionIterateOnly// DMACommand will be used as a cursor only
104  	};
105  
106  	struct SegmentOptions {
107  		uint8_t  fStructSize;
108  		uint8_t  fNumAddressBits;
109  		uint64_t fMaxSegmentSize;
110  		uint64_t fMaxTransferSize;
111  		uint32_t fAlignment;
112  		uint32_t fAlignmentLength;
113  		uint32_t fAlignmentInternalSegments;
114  	};
115  
116  /*! @enum SynchronizeOptions
117   *   @abstract Options for the synchronize method.
118   *   @constant kForceDoubleBuffer Copy the entire prepared range to a new page aligned buffer.
119   */
120  	enum SynchronizeOptions {
121  		kForceDoubleBuffer = 0x01000000
122  	};
123  
124  /*!
125   *   @typedef SegmentFunction
126   *   @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.
127   *   @param segment The 64Bit I/O bus address and length.
128   *   @param segments Base of the output vector of DMA address length pairs.
129   *   @param segmentIndex Index to output 'segment' in the 'segments' array.
130   *   @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.
131   */
132  	typedef bool (*SegmentFunction)(IODMACommand *target,
133  	    Segment64 segment,
134  	    void     *segments,
135  	    UInt32    segmentIndex);
136  
137  // -------------- Preimplemented output functions ----------------
138  
139  /*! @function OutputHost32
140   *   @abstract Output host natural Segment32 output segment function.
141   */
142  	static bool OutputHost32(IODMACommand *target,
143  	    Segment64 seg, void *segs, UInt32 ind);
144  
145  /*! @defined kIODMACommandOutputHost32
146   *   @abstract Output host natural Segment32 output segment function.
147   */
148  #define kIODMACommandOutputHost32   (IODMACommand::OutputHost32)
149  
150  /*! @function OutputBig32
151   *   @abstract Output big-endian Segment32 output segment function.
152   */
153  	static bool OutputBig32(IODMACommand *target,
154  	    Segment64 seg, void *segs, UInt32 ind);
155  
156  /*! @defined kIODMACommandOutputBig32
157   *   @abstract Output big-endian Segment32 output segment function.
158   */
159  #define kIODMACommandOutputBig32    (IODMACommand::OutputBig32)
160  
161  /*! @function OutputLittle32
162   *   @abstract Output little-endian Segment32 output segment function.
163   */
164  	static bool OutputLittle32(IODMACommand *target,
165  	    Segment64 seg, void *segs, UInt32 ind);
166  
167  /*! @defined kIODMACommandOutputLittle32
168   *   @abstract Output little-endian Segment32 output segment function.
169   */
170  #define kIODMACommandOutputLittle32 (IODMACommand::OutputLittle32)
171  
172  /*! @function OutputHost64
173   *   @abstract Output host natural Segment64 output segment function.
174   */
175  	static bool OutputHost64(IODMACommand *target,
176  	    Segment64 seg, void *segs, UInt32 ind);
177  
178  /*! @defined kIODMACommandOutputHost64
179   *   @abstract Output host natural Segment64 output segment function.
180   */
181  #define kIODMACommandOutputHost64   (IODMACommand::OutputHost64)
182  
183  /*! @function OutputBig64
184   *   @abstract Output big-endian Segment64 output segment function.
185   */
186  	static bool OutputBig64(IODMACommand *target,
187  	    Segment64 seg, void *segs, UInt32 ind);
188  
189  /*! @defined kIODMACommandOutputBig64
190   *   @abstract Output big-endian Segment64 output segment function.
191   */
192  #define kIODMACommandOutputBig64    (IODMACommand::OutputBig64)
193  
194  /*! @function OutputLittle64
195   *   @abstract Output little-endian Segment64 output segment function.
196   */
197  	static bool OutputLittle64(IODMACommand *target,
198  	    Segment64 seg, void *segs, UInt32 ind);
199  
200  /*! @defined kIODMACommandOutputLittle64
201   *   @abstract Output little-endian Segment64 output segment function.
202   */
203  #define kIODMACommandOutputLittle64 (IODMACommand::OutputLittle64)
204  
205  /*! @function withSpecification
206   *   @abstract Creates and initializes an IODMACommand in one operation.
207   *   @discussion Factory function to create and initialize an IODMACommand in one operation.
208   *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
209   *   @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.
210   *   @param maxSegmentSize Maximum allowable size for one segment.  If 0 is passed the maximum segment size is unlimited.
211   *   @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.
212   *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
213   *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
214   *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
215   *   @param refCon Reference Constant
216   *   @result Returns a new IODMACommand if successfully created and initialized, 0 otherwise.
217   */
218  	static OSPtr<IODMACommand>
219  	withSpecification(SegmentFunction  outSegFunc,
220  	    UInt8            numAddressBits,
221  	    UInt64           maxSegmentSize,
222  	    MappingOptions   mappingOptions = kMapped,
223  	    UInt64           maxTransferSize = 0,
224  	    UInt32           alignment = 1,
225  	    IOMapper        *mapper = NULL,
226  	    void            *refCon = NULL);
227  
228  /*! @function weakWithSpecification
229   *   @abstract Creates and initialises an IODMACommand in one operation if this version of the operating system supports it.
230   *   @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.).
231   *   @param newCommand Output reference variable of the newly created IODMACommand.
232   *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
233   *   @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.
234   *   @param maxSegmentSize Maximum allowable size for one segment. Zero is treated as an unlimited segment size.
235   *   @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.
236   *   @param maxTransferSize Maximum size of an entire transfer.  Defaults to 0 indicating no maximum.
237   *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
238   *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
239   *   @param refCon Reference Constant
240   *   @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.
241   */
242  // Note that the function has the attribute always_inline.
243  // The point of this function is to make a call into the kernel
244  // without generating an undefined symbol.  If the client could call
245  // the code as a function then the goal of no undefined symbols
246  // would be lost thus defeating the purpose.
247  	static inline IOReturn weakWithSpecification
248  	(IODMACommand   **newCommand,
249  	    SegmentFunction outSegFunc,
250  	    UInt8           numAddressBits,
251  	    UInt64          maxSegmentSize,
252  	    MappingOptions  mapType = kMapped,
253  	    UInt64          maxTransferSize = 0,
254  	    UInt32          alignment = 1,
255  	    IOMapper       *mapper = NULL,
256  	    void           *refCon = NULL) __attribute__((always_inline));
257  
258  	static OSPtr<IODMACommand>
259  	withSpecification(SegmentFunction        outSegFunc,
260  	    const SegmentOptions * segmentOptions,
261  	    uint32_t               mappingOptions,
262  	    IOMapper             * mapper,
263  	    void                 * refCon);
264  
265  
266  /*! @function withRefCon
267   *   @abstract Creates and initializes an unspecified IODMACommand.
268   *   @discussion Factory function to create and initialize an unspecified IODMACommand. prepareWithSpecification() must be used to prepare the IODMACommand before use.
269   *   @param refCon Reference Constant
270   *   @result Returns a new IODMACommand if successfully created and initialized, 0 otherwise.
271   */
272  	static OSPtr<IODMACommand> withRefCon(void * refCon);
273  
274  /*!
275   *   @function cloneCommand
276   *   @abstract Creates a new command based on the specification of the current one.
277   *   @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.
278   *   @result Returns a new IODMACommand if successfully created and initialised, 0 otherwise.
279   */
280  	virtual OSPtr<IODMACommand> cloneCommand(void *refCon = NULL);
281  
282  /*! @function initWithSpecification
283   *   @abstract Primary initializer for the IODMACommand class.
284   *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
285   *   @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.
286   *   @param maxSegmentSize Maximum allowable size for one segment.  Defaults to 0 which means any size.
287   *   @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.
288   *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
289   *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
290   *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
291   *   @param refCon Reference Constant
292   *   @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.
293   */
294  	virtual bool initWithSpecification( SegmentFunction  outSegFunc,
295  	    UInt8     numAddressBits,
296  	    UInt64    maxSegmentSize,
297  	    MappingOptions mappingOptions = kMapped,
298  	    UInt64    maxTransferSize = 0,
299  	    UInt32    alignment = 1,
300  	    IOMapper *mapper = NULL,
301  	    void     *refCon = NULL);
302  
303  /*! @function setMemoryDescriptor
304   *   @abstract Sets and resets the DMACommand's current memory descriptor
305   *   @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.
306   *   @param mem A pointer to the current I/Os memory descriptor.
307   *   @param autoPrepare An optional boolean variable that will call the prepare() function automatically after the memory descriptor is processed. Defaults to true.
308   *   @result Returns kIOReturnSuccess, kIOReturnBusy if currently prepared, kIOReturnNoSpace if the length(mem) >= Maximum Transfer Size or the error codes returned by prepare() (qv).
309   */
310  	virtual IOReturn setMemoryDescriptor(const IOMemoryDescriptor *mem,
311  	    bool autoPrepare = true);
312  
313  /*! @function clearMemoryDescriptor
314   *   @abstract Clears the DMACommand's current memory descriptor
315   *   @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.
316   *   @param autoComplete An optional boolean variable that will call the complete() function automatically before the memory descriptor is processed. Defaults to true.
317   */
318  	virtual IOReturn clearMemoryDescriptor(bool autoComplete = true);
319  
320  /*! @function getMemoryDescriptor
321   *   @abstract Get the current memory descriptor
322   */
323  	virtual const IOMemoryDescriptor * getMemoryDescriptor() const;
324  
325  /*! @function getIOMemoryDescriptor
326   *   @abstract Get the memory descriptor to be used for DMA
327   */
328  	IOMemoryDescriptor * getIOMemoryDescriptor() const;
329  
330  /*! @function prepare
331   *   @abstract Prepare the memory for an I/O transfer.
332   *   @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.
333   *   @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.
334   *   @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.
335   *   @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.
336   *   @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.
337   *   @result An IOReturn code. */
338  
339  	virtual IOReturn prepare(UInt64 offset = 0, UInt64 length = 0, bool flushCache = true, bool synchronize = true);
340  
341  /*! @function complete
342   *   @abstract Complete processing of DMA mappings after an I/O transfer is finished.
343   *   @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
344   *   @param invalidateCache Invalidate the caches for the memory descriptor.  Defaults to true for kNonCoherent and is ignored by the other types.
345   *   @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.
346   *   @result kIOReturnNotReady if not prepared, kIOReturnSuccess otherwise. */
347  
348  	virtual IOReturn complete(bool invalidateCache = true, bool synchronize = true);
349  
350  /*! @function synchronize
351   *   @abstract Bring IOMemoryDescriptor and IODMACommand buffers into sync.
352   *   @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.
353   *   @param options Specifies the direction of the copy:
354   *       kIODirectionOut copy IOMemoryDesciptor memory to any IODMACommand buffers. By default this action takes place automatically at prepare().
355   *       kIODirectionIn copy any IODMACommand buffers back to the IOMemoryDescriptor. By default this action takes place automatically at complete().
356   *       kForceDoubleBuffer copy the entire prepared range to a new page aligned buffer.
357   *   @result kIOReturnNotReady if not prepared, kIOReturnBadArgument if invalid options are passed, kIOReturnSuccess otherwise. */
358  
359  	virtual IOReturn synchronize(IOOptionBits options);
360  
361  /*! @function genIOVMSegments
362   *   @abstract Generates a physical scatter/gather for the current DMA command
363   *   @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.
364   *   @param offset input/output parameter, defines the starting and ending offset in the memory descriptor, relative to any offset passed to the prepare() method.
365   *   @param segments Void pointer to base of output physical scatter/gather list.  Always passed directly onto the SegmentFunction.
366   *   @param numSegments Input/output parameter Number of segments that can fit in the segment array and returns number of segments generated.
367   *   @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.
368   */
369  	virtual IOReturn genIOVMSegments(UInt64 *offset,
370  	    void   *segments,
371  	    UInt32 *numSegments);
372  
373  private:
374  	virtual UInt64 transfer( IOOptionBits transferOp, UInt64 offset, void * buffer, UInt64 length );
375  
376  public:
377  
378  /*! @function writeBytes
379   *   @abstract Copy data to the IODMACommand's buffer from the specified buffer.
380   *   @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.
381   *   @param offset A byte offset into the IODMACommand's memory, relative to the prepared offset.
382   *   @param bytes The caller supplied buffer to copy the data from.
383   *   @param length The length of the data to copy.
384   *   @result The number of bytes copied, zero will be returned if the specified offset is beyond the prepared length of the IODMACommand. */
385  
386  	UInt64 writeBytes(UInt64 offset, const void *bytes, UInt64 length);
387  
388  /*! @function readBytes
389   *   @abstract Copy data from the IODMACommand's buffer to the specified buffer.
390   *   @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.
391   *   @param offset A byte offset into the IODMACommand's memory, relative to the prepared offset.
392   *   @param bytes The caller supplied buffer to copy the data to.
393   *   @param length The length of the data to copy.
394   *   @result The number of bytes copied, zero will be returned if the specified offset is beyond the prepared length of the IODMACommand. */
395  
396  	UInt64 readBytes(UInt64 offset, void *bytes, UInt64 length);
397  
398  /*! @function gen32IOVMSegments
399   *   @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.
400   */
401  	inline IOReturn
402  	gen32IOVMSegments(UInt64   *offset,
403  	    Segment32 *segments,
404  	    UInt32     *numSegments)
405  	{
406  		return genIOVMSegments(offset, segments, numSegments);
407  	}
408  
409  /*! @function gen64IOVMSegments
410   *   @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.
411   */
412  	inline IOReturn
413  	gen64IOVMSegments(UInt64    *offset,
414  	    Segment64 *segments,
415  	    UInt32    *numSegments)
416  	{
417  		return genIOVMSegments(offset, segments, numSegments);
418  	}
419  
420  	IOReturn
421  	genIOVMSegments(SegmentFunction segmentFunction,
422  	    UInt64 *offsetP,
423  	    void   *segmentsP,
424  	    UInt32 *numSegmentsP);
425  
426  	virtual void free() APPLE_KEXT_OVERRIDE;
427  
428  private:
429  	IOReturn setSpecification(SegmentFunction        outSegFunc,
430  	    const SegmentOptions * segmentOptions,
431  	    uint32_t               mappingOptions,
432  	    IOMapper             * mapper);
433  
434  	typedef IOReturn (*InternalSegmentFunction)(
435  		void         *reference,
436  		IODMACommand *target,
437  		Segment64     segment,
438  		void         *segments,
439  		UInt32        segmentIndex);
440  
441  	IOReturn genIOVMSegments(uint32_t op,
442  	    InternalSegmentFunction outSegFunc,
443  	    void   *reference,
444  	    UInt64 *offsetP,
445  	    void   *segmentsP,
446  	    UInt32 *numSegmentsP);
447  
448  	static IOReturn clientOutputSegment(
449  		void *reference, IODMACommand *target,
450  		Segment64 segment, void *vSegList, UInt32 outSegIndex);
451  
452  	static IOReturn segmentOp(
453  		void         *reference,
454  		IODMACommand *target,
455  		Segment64     segment,
456  		void         *segments,
457  		UInt32        segmentIndex);
458  	IOReturn walkAll(uint32_t op);
459  
460  public:
461  
462  /*! @function prepareWithSpecification
463   *   @abstract Prepare the memory for an I/O transfer with a new specification.
464   *   @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.
465   *   @param outSegFunc SegmentFunction to call to output one physical segment. A set of nine commonly required segment functions are provided.
466   *   @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.
467   *   @param maxSegmentSize Maximum allowable size for one segment.  Defaults to 0 which means any size.
468   *   @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.
469   *   @param maxTransferSize Maximum size of an entire transfer.	Defaults to 0 indicating no maximum.
470   *   @param alignment Alignment restriction, in bytes, on I/O bus addresses.  Defaults to single byte alignment.
471   *   @param mapper For mapping types kMapped & kBypassed mapper is used to define the hardware that will perform the mapping, defaults to the system mapper.
472   *   @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.
473   *   @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.
474   *   @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.
475   *   @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.
476   *   @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.
477   */
478  
479  	virtual IOReturn prepareWithSpecification(SegmentFunction   outSegFunc,
480  	    UInt8             numAddressBits,
481  	    UInt64            maxSegmentSize,
482  	    MappingOptions    mappingOptions = kMapped,
483  	    UInt64            maxTransferSize = 0,
484  	    UInt32            alignment = 1,
485  	    IOMapper          *mapper = NULL,
486  	    UInt64            offset = 0,
487  	    UInt64            length = 0,
488  	    bool              flushCache = true,
489  	    bool              synchronize = true);
490  
491  	static IOReturn transferSegment(void         *reference,
492  	    IODMACommand *target,
493  	    Segment64     segment,
494  	    void         *segments,
495  	    UInt32        segmentIndex);
496  
497  /*! @function getPreparedOffsetAndLength
498   *   @abstract Returns the offset and length into the target IOMemoryDescriptor of a prepared IODDMACommand.
499   *   @discussion If successfully prepared, returns the offset and length into the IOMemoryDescriptor. Will fail for an unprepared IODMACommand.
500   *   @param offset returns the starting offset in the memory descriptor the DMA command was prepared with. Pass NULL for don't care.
501   *   @param length returns the length in the memory descriptor the DMA command was prepared with. Pass NULL for don't care.
502   *   @result An IOReturn code. kIOReturnNotReady if the IODMACommand is not prepared. */
503  
504  	virtual IOReturn getPreparedOffsetAndLength(UInt64 * offset, UInt64 * length);
505  
506  	UInt8    getNumAddressBits(void);
507  	UInt32   getAlignment(void);
508  	uint32_t getAlignmentLength(void);
509  	uint32_t getAlignmentInternalSegments(void);
510  
511  
512  /*! @function initWithRefCon
513   *   @abstract Secondary initializer for the IODMACommand class.
514   *   @param refCon Reference Constant
515   *   @result Can fail if super init fails.  Returns true otherwise.
516   */
517  
518  	virtual
519  	bool initWithRefCon(void * refCon = NULL);
520  
521  	virtual
522  	bool initWithSpecification(SegmentFunction        outSegFunc,
523  	    const SegmentOptions * segmentOptions,
524  	    uint32_t               mappingOptions,
525  	    IOMapper             * mapper,
526  	    void                 * refCon);
527  
528  	virtual
529  	IOReturn prepareWithSpecification(SegmentFunction        outSegFunc,
530  	    const SegmentOptions * segmentOptions,
531  	    uint32_t               mappingOptions,
532  	    IOMapper             * mapper,
533  	    uint64_t               offset,
534  	    uint64_t               length,
535  	    bool                   flushCache = true,
536  	    bool                   synchronize = true);
537  
538  	virtual
539  	OSPtr<IOBufferMemoryDescriptor> createCopyBuffer(IODirection direction, UInt64 length);
540  
541  private:
542  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 0);
543  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 1);
544  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 2);
545  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 3);
546  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 4);
547  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 5);
548  	OSMetaClassDeclareReservedUsedX86(IODMACommand, 6);
549  	OSMetaClassDeclareReservedUnused(IODMACommand, 7);
550  	OSMetaClassDeclareReservedUnused(IODMACommand, 8);
551  	OSMetaClassDeclareReservedUnused(IODMACommand, 9);
552  	OSMetaClassDeclareReservedUnused(IODMACommand, 10);
553  	OSMetaClassDeclareReservedUnused(IODMACommand, 11);
554  	OSMetaClassDeclareReservedUnused(IODMACommand, 12);
555  	OSMetaClassDeclareReservedUnused(IODMACommand, 13);
556  	OSMetaClassDeclareReservedUnused(IODMACommand, 14);
557  	OSMetaClassDeclareReservedUnused(IODMACommand, 15);
558  
559  public:
560  /*! @var fRefCon Reference Constant, client defined publicly avialable */
561  	void *fRefCon;
562  
563  protected:
564  
565  /*! @var fMaxSegmentSize Maximum size of one segment in a scatter/gather list */
566  	UInt64  fMaxSegmentSize;
567  
568  /*! @var fMaxTransferSize
569   *   Maximum size of a transfer that this memory cursor is allowed to generate */
570  	UInt64  fMaxTransferSize;
571  
572  	UInt32  fAlignMaskLength;
573  	UInt32  fAlignMaskInternalSegments;
574  
575  /*! @var fMapper
576   *   Client defined mapper. */
577  	OSPtr<IOMapper> fMapper;
578  
579  /*! @var fMemory
580   *   memory descriptor for current I/O. */
581  	OSPtr<IOMemoryDescriptor> fMemory;
582  
583  /*! @var fOutSeg The action method called when an event has been delivered */
584  	SegmentFunction fOutSeg;
585  
586  /*! @var fAlignMask
587   *   Alignment restriction mask. */
588  	UInt32  fAlignMask;
589  
590  /*! @var fNumAddressBits
591   *   Number of bits that the hardware can address */
592  	UInt32 fNumAddressBits;
593  
594  /*! @var fNumSegments
595   *   Number of contiguous segments required for the current memory descriptor and desired mapping */
596  	UInt32  fNumSegments;
597  
598  /*! @var fMappingOptions
599   *   What type of I/O virtual address mapping is required for this command */
600  	uint32_t  fMappingOptions;
601  
602  /*! @var fActive
603   *   fActive indicates that this DMA command is currently prepared and ready to go */
604  	UInt32 fActive;
605  
606  /*! @var reserved
607   *   Reserved for future use.  (Internal use only)  */
608  	struct IODMACommandInternal  *reserved;
609  };
610  
611  IOReturn
612  IODMACommand::
613  weakWithSpecification(IODMACommand **newCommand,
614      SegmentFunction  outSegFunc,
615      UInt8     numAddressBits,
616      UInt64    maxSegmentSize,
617      MappingOptions mapType,
618      UInt64    maxTransferSize,
619      UInt32    alignment,
620      IOMapper *mapper,
621      void     *refCon)
622  {
623  	if (!newCommand) {
624  		return kIOReturnBadArgument;
625  	}
626  
627  	IODMACommand *self = (IODMACommand *)
628  	    OSMetaClass::allocClassWithName("IODMACommand");
629  	if (!self) {
630  		return kIOReturnUnsupported;
631  	}
632  
633  	IOReturn ret;
634  	bool inited = self->
635  	    initWithSpecification(outSegFunc,
636  	    numAddressBits, maxSegmentSize, mapType,
637  	    maxTransferSize, alignment, mapper, refCon);
638  	if (inited) {
639  		ret =  kIOReturnSuccess;
640  	} else {
641  		self->release();
642  		self = NULL;
643  		ret = kIOReturnError;
644  	}
645  
646  	*newCommand = self;
647  	return ret;
648  };
649  #endif /* !_IODMACOMMAND_H */