]> git.saurik.com Git - apple/xnu.git/blame - iokit/IOKit/IODMACommand.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / iokit / IOKit / IODMACommand.h
CommitLineData
0c530ab8 1/*
39037602 2 * Copyright (c) 2005-2016 Apple Inc. All rights reserved.
0c530ab8 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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.
0a7de745 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
2d21ac55
A
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
0c530ab8
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
0c530ab8
A
27 */
28#ifndef _IODMACOMMAND_H
29#define _IODMACOMMAND_H
30
31#include <IOKit/IOCommand.h>
32#include <IOKit/IOMemoryDescriptor.h>
eb6b6ca3 33#include <DriverKit/IODMACommand.h>
0c530ab8 34class IOMapper;
3e170ce0 35class IOBufferMemoryDescriptor;
0c530ab8 36
0a7de745
A
37enum{
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
39037602
A
47};
48
0c530ab8
A
49/**************************** class IODMACommand ***************************/
50
51/*!
0a7de745
A
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 */
0c530ab8
A
62
63class IODMACommand : public IOCommand
64{
eb6b6ca3 65 OSDeclareDefaultStructorsWithDispatch(IODMACommand);
0c530ab8 66
0a7de745 67 friend class IODMAEventSource;
2d21ac55 68
0c530ab8
A
69public:
70
71/*!
0a7de745
A
72 * @typedef Segment32
73 * @discussion A 32 bit I/O bus address/length pair
74 */
75 struct Segment32 {
76 UInt32 fIOVMAddr, fLength;
77 };
0c530ab8
A
78
79/*!
0a7de745
A
80 * @typedef Segment64
81 * @discussion A 64 bit I/O bus address/length pair
82 */
83 struct Segment64 {
84 UInt64 fIOVMAddr, fLength;
85 };
0c530ab8
A
86
87/*! @enum MappingOptions
0a7de745
A
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 };
0c530ab8
A
115
116/*! @enum SynchronizeOptions
0a7de745
A
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 };
0c530ab8
A
123
124/*!
0a7de745
A
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 ----------------
0c530ab8
A
138
139/*! @function OutputHost32
0a7de745
A
140 * @abstract Output host natural Segment32 output segment function.
141 */
142 static bool OutputHost32(IODMACommand *target,
0c530ab8
A
143 Segment64 seg, void *segs, UInt32 ind);
144
145/*! @defined kIODMACommandOutputHost32
0a7de745 146 * @abstract Output host natural Segment32 output segment function.
0c530ab8
A
147 */
148#define kIODMACommandOutputHost32 (IODMACommand::OutputHost32)
149
150/*! @function OutputBig32
0a7de745
A
151 * @abstract Output big-endian Segment32 output segment function.
152 */
153 static bool OutputBig32(IODMACommand *target,
0c530ab8
A
154 Segment64 seg, void *segs, UInt32 ind);
155
156/*! @defined kIODMACommandOutputBig32
0a7de745 157 * @abstract Output big-endian Segment32 output segment function.
0c530ab8
A
158 */
159#define kIODMACommandOutputBig32 (IODMACommand::OutputBig32)
160
161/*! @function OutputLittle32
0a7de745
A
162 * @abstract Output little-endian Segment32 output segment function.
163 */
164 static bool OutputLittle32(IODMACommand *target,
0c530ab8
A
165 Segment64 seg, void *segs, UInt32 ind);
166
167/*! @defined kIODMACommandOutputLittle32
0a7de745
A
168 * @abstract Output little-endian Segment32 output segment function.
169 */
0c530ab8
A
170#define kIODMACommandOutputLittle32 (IODMACommand::OutputLittle32)
171
172/*! @function OutputHost64
0a7de745
A
173 * @abstract Output host natural Segment64 output segment function.
174 */
175 static bool OutputHost64(IODMACommand *target,
0c530ab8
A
176 Segment64 seg, void *segs, UInt32 ind);
177
178/*! @defined kIODMACommandOutputHost64
0a7de745
A
179 * @abstract Output host natural Segment64 output segment function.
180 */
0c530ab8
A
181#define kIODMACommandOutputHost64 (IODMACommand::OutputHost64)
182
183/*! @function OutputBig64
0a7de745
A
184 * @abstract Output big-endian Segment64 output segment function.
185 */
186 static bool OutputBig64(IODMACommand *target,
0c530ab8
A
187 Segment64 seg, void *segs, UInt32 ind);
188
fe8ab488 189/*! @defined kIODMACommandOutputBig64
0a7de745
A
190 * @abstract Output big-endian Segment64 output segment function.
191 */
0c530ab8
A
192#define kIODMACommandOutputBig64 (IODMACommand::OutputBig64)
193
194/*! @function OutputLittle64
0a7de745
A
195 * @abstract Output little-endian Segment64 output segment function.
196 */
197 static bool OutputLittle64(IODMACommand *target,
0c530ab8
A
198 Segment64 seg, void *segs, UInt32 ind);
199
fe8ab488 200/*! @defined kIODMACommandOutputLittle64
0a7de745
A
201 * @abstract Output little-endian Segment64 output segment function.
202 */
0c530ab8
A
203#define kIODMACommandOutputLittle64 (IODMACommand::OutputLittle64)
204
205/*! @function withSpecification
0a7de745
A
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 */
f427ee49 218 static OSPtr<IODMACommand>
0c530ab8 219 withSpecification(SegmentFunction outSegFunc,
0a7de745
A
220 UInt8 numAddressBits,
221 UInt64 maxSegmentSize,
222 MappingOptions mappingOptions = kMapped,
223 UInt64 maxTransferSize = 0,
224 UInt32 alignment = 1,
cb323159
A
225 IOMapper *mapper = NULL,
226 void *refCon = NULL);
0c530ab8
A
227
228/*! @function weakWithSpecification
0a7de745
A
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,
cb323159
A
255 IOMapper *mapper = NULL,
256 void *refCon = NULL) __attribute__((always_inline));
0a7de745 257
f427ee49 258 static OSPtr<IODMACommand>
3e170ce0 259 withSpecification(SegmentFunction outSegFunc,
0a7de745
A
260 const SegmentOptions * segmentOptions,
261 uint32_t mappingOptions,
262 IOMapper * mapper,
263 void * refCon);
3e170ce0
A
264
265
266/*! @function withRefCon
0a7de745
A
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 */
f427ee49 272 static OSPtr<IODMACommand> withRefCon(void * refCon);
3e170ce0 273
0c530ab8 274/*!
0a7de745
A
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 */
f427ee49 280 virtual OSPtr<IODMACommand> cloneCommand(void *refCon = NULL);
0c530ab8
A
281
282/*! @function initWithSpecification
0a7de745
A
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,
cb323159
A
300 IOMapper *mapper = NULL,
301 void *refCon = NULL);
0c530ab8
A
302
303/*! @function setMemoryDescriptor
0a7de745
A
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);
0c530ab8
A
312
313/*! @function clearMemoryDescriptor
0a7de745
A
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);
0c530ab8
A
319
320/*! @function getMemoryDescriptor
0a7de745
A
321 * @abstract Get the current memory descriptor
322 */
f427ee49 323 virtual const IOMemoryDescriptor * getMemoryDescriptor() const;
0c530ab8 324
3e170ce0 325/*! @function getIOMemoryDescriptor
0a7de745
A
326 * @abstract Get the memory descriptor to be used for DMA
327 */
328 IOMemoryDescriptor * getIOMemoryDescriptor() const;
3e170ce0 329
0c530ab8 330/*! @function prepare
0a7de745
A
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. */
0c530ab8 338
0a7de745 339 virtual IOReturn prepare(UInt64 offset = 0, UInt64 length = 0, bool flushCache = true, bool synchronize = true);
0c530ab8
A
340
341/*! @function complete
0a7de745
A
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. */
0c530ab8 347
0a7de745 348 virtual IOReturn complete(bool invalidateCache = true, bool synchronize = true);
0c530ab8
A
349
350/*! @function synchronize
0a7de745
A
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. */
0c530ab8 358
0a7de745 359 virtual IOReturn synchronize(IOOptionBits options);
0c530ab8
A
360
361/*! @function genIOVMSegments
0a7de745
A
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);
0c530ab8 372
2d21ac55 373private:
0a7de745 374 virtual UInt64 transfer( IOOptionBits transferOp, UInt64 offset, void * buffer, UInt64 length );
2d21ac55
A
375
376public:
377
378/*! @function writeBytes
0a7de745
A
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. */
2d21ac55 385
0a7de745 386 UInt64 writeBytes(UInt64 offset, const void *bytes, UInt64 length);
2d21ac55
A
387
388/*! @function readBytes
0a7de745
A
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. */
2d21ac55 395
0a7de745 396 UInt64 readBytes(UInt64 offset, void *bytes, UInt64 length);
2d21ac55 397
0c530ab8 398/*! @function gen32IOVMSegments
0a7de745
A
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 }
0c530ab8
A
408
409/*! @function gen64IOVMSegments
0a7de745
A
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;
0c530ab8
A
427
428private:
0a7de745
A
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);
f427ee49 458 IOReturn walkAll(uint32_t op);
0c530ab8 459
2d21ac55
A
460public:
461
462/*! @function prepareWithSpecification
0a7de745
A
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,
cb323159 485 IOMapper *mapper = NULL,
0a7de745
A
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);
2d21ac55 496
b0d623f7 497/*! @function getPreparedOffsetAndLength
0a7de745
A
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. */
b0d623f7 503
0a7de745 504 virtual IOReturn getPreparedOffsetAndLength(UInt64 * offset, UInt64 * length);
b0d623f7 505
0a7de745
A
506 UInt8 getNumAddressBits(void);
507 UInt32 getAlignment(void);
508 uint32_t getAlignmentLength(void);
509 uint32_t getAlignmentInternalSegments(void);
3e170ce0
A
510
511
512/*! @function initWithRefCon
0a7de745
A
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
cb323159 519 bool initWithRefCon(void * refCon = NULL);
0a7de745
A
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
f427ee49 539 OSPtr<IOBufferMemoryDescriptor> createCopyBuffer(IODirection direction, UInt64 length);
0a7de745 540
0c530ab8 541private:
f427ee49
A
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);
0a7de745
A
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);
0c530ab8
A
558
559public:
560/*! @var fRefCon Reference Constant, client defined publicly avialable */
0a7de745 561 void *fRefCon;
0c530ab8
A
562
563protected:
564
565/*! @var fMaxSegmentSize Maximum size of one segment in a scatter/gather list */
0a7de745 566 UInt64 fMaxSegmentSize;
0c530ab8
A
567
568/*! @var fMaxTransferSize
0a7de745
A
569 * Maximum size of a transfer that this memory cursor is allowed to generate */
570 UInt64 fMaxTransferSize;
0c530ab8 571
0a7de745
A
572 UInt32 fAlignMaskLength;
573 UInt32 fAlignMaskInternalSegments;
0c530ab8
A
574
575/*! @var fMapper
0a7de745 576 * Client defined mapper. */
f427ee49 577 OSPtr<IOMapper> fMapper;
0c530ab8
A
578
579/*! @var fMemory
0a7de745 580 * memory descriptor for current I/O. */
f427ee49 581 OSPtr<IOMemoryDescriptor> fMemory;
0c530ab8
A
582
583/*! @var fOutSeg The action method called when an event has been delivered */
0a7de745 584 SegmentFunction fOutSeg;
0c530ab8
A
585
586/*! @var fAlignMask
0a7de745
A
587 * Alignment restriction mask. */
588 UInt32 fAlignMask;
0c530ab8
A
589
590/*! @var fNumAddressBits
0a7de745
A
591 * Number of bits that the hardware can address */
592 UInt32 fNumAddressBits;
0c530ab8
A
593
594/*! @var fNumSegments
0a7de745
A
595 * Number of contiguous segments required for the current memory descriptor and desired mapping */
596 UInt32 fNumSegments;
0c530ab8
A
597
598/*! @var fMappingOptions
0a7de745
A
599 * What type of I/O virtual address mapping is required for this command */
600 uint32_t fMappingOptions;
0c530ab8
A
601
602/*! @var fActive
0a7de745
A
603 * fActive indicates that this DMA command is currently prepared and ready to go */
604 UInt32 fActive;
0c530ab8
A
605
606/*! @var reserved
0a7de745 607 * Reserved for future use. (Internal use only) */
f427ee49 608 struct IODMACommandInternal *reserved;
0c530ab8
A
609};
610
0a7de745
A
611IOReturn
612IODMACommand::
0c530ab8 613weakWithSpecification(IODMACommand **newCommand,
0a7de745
A
614 SegmentFunction outSegFunc,
615 UInt8 numAddressBits,
616 UInt64 maxSegmentSize,
617 MappingOptions mapType,
618 UInt64 maxTransferSize,
619 UInt32 alignment,
620 IOMapper *mapper,
621 void *refCon)
0c530ab8 622{
0a7de745
A
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();
cb323159 642 self = NULL;
0a7de745
A
643 ret = kIOReturnError;
644 }
645
646 *newCommand = self;
647 return ret;
0c530ab8
A
648};
649#endif /* !_IODMACOMMAND_H */