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