1 | /* |
2 | * Copyright (c) 1998-2000 Apple Computer, 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 _IOMEMORYCURSOR_H |
29 | #define _IOMEMORYCURSOR_H |
30 | |
31 | #include <libkern/c++/OSObject.h> |
32 | #include <IOKit/IOTypes.h> |
33 | |
34 | class IOMemoryDescriptor; |
35 | |
36 | /**************************** class IOMemoryCursor ***************************/ |
37 | |
38 | /*! |
39 | @class IOMemoryCursor |
40 | @abstract A mechanism to convert memory references to physical addresses. |
41 | @discussion The IOMemoryCursor declares the super class that all |
42 | specific memory cursors must inherit from, but a memory cursor can be created without a specific format subclass by just providing a segment function to the initializers. This class does the difficult stuff of dividing a memory descriptor into a physical scatter/gather list appropriate for the target hardware. |
43 | <br><br> |
44 | A driver is expected to create a memory cursor and configure it to the limitations of its DMA hardware; for instance the memory cursor used by the FireWire SBP-2 protocol has a maximum physical segment size of 2^16 - 1 but the actual transfer size is unlimited. Thus it would create a cursor with a maxSegmentSize of 65535 and a maxTransfer size of UINT_MAX. It would also provide a SegmentFunction that can output a pagelist entry. |
45 | <br><br> |
46 | Below is the simplest example of a SegmentFunction:<br> |
47 | void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,<br> |
48 | void * outSegments,<br> |
49 | UInt32 outSegmentIndex)<br> |
50 | {<br> |
51 | ((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;<br> |
52 | } |
53 | |
54 | */ |
55 | class IOMemoryCursor : public OSObject |
56 | { |
57 | OSDeclareDefaultStructors(IOMemoryCursor) |
58 | |
59 | public: |
60 | /*! |
61 | @typedef PhysicalSegment |
62 | @discussion A physical address/length pair. |
63 | */ |
64 | struct PhysicalSegment |
65 | { |
66 | IOPhysicalAddress location; |
67 | IOPhysicalLength length; |
68 | }; |
69 | |
70 | /*! @defined IOPhysicalSegment |
71 | @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::PhysicalSegment |
72 | */ |
73 | #define IOPhysicalSegment IOMemoryCursor::PhysicalSegment |
74 | |
75 | /*! |
76 | @typedef SegmentFunction |
77 | @discussion Pointer to a C function that outputs a single physical segment to an element in the array as defined by the segments and segmentIndex parameters. |
78 | @param segment The physical address and length that is next to be output. |
79 | @param segments Base of the output vector of DMA address length pairs. |
80 | @param segmentIndex Index to output 'segment' in the 'segments' array. |
81 | */ |
82 | typedef void (*SegmentFunction)(PhysicalSegment segment, |
83 | void * segments, |
84 | UInt32 segmentIndex); |
85 | |
86 | /*! @defined OutputSegmentFunc |
87 | @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::SegmentFunction */ |
88 | #define OutputSegmentFunc IOMemoryCursor::SegmentFunction |
89 | |
90 | protected: |
91 | /*! @var outSeg The action method called when an event has been delivered */ |
92 | SegmentFunction outSeg; |
93 | |
94 | /*! @var maxSegmentSize Maximum size of one segment in a scatter/gather list */ |
95 | IOPhysicalLength maxSegmentSize; |
96 | |
97 | /*! @var maxTransferSize |
98 | Maximum size of a transfer that this memory cursor is allowed to generate */ |
99 | IOPhysicalLength maxTransferSize; |
100 | |
101 | /*! @var alignMask |
102 | Currently unused. Reserved for automated aligment restriction code. */ |
103 | IOPhysicalLength alignMask; |
104 | |
105 | public: |
106 | /*! @function withSpecification |
107 | @abstract Creates and initializes an IOMemoryCursor in one operation. |
108 | @discussion Factory function to create and initialize an IOMemoryCursor in one operation. For more information, see IOMemoryCursor::initWithSpecification. |
109 | @param outSegFunc SegmentFunction to call to output one physical segment. |
110 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
111 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
112 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
113 | @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. |
114 | */ |
115 | static IOMemoryCursor * |
116 | withSpecification(SegmentFunction outSegFunc, |
117 | IOPhysicalLength maxSegmentSize = 0, |
118 | IOPhysicalLength maxTransferSize = 0, |
119 | IOPhysicalLength alignment = 1); |
120 | |
121 | /*! @function initWithSpecification |
122 | @abstract Primary initializer for the IOMemoryCursor class. |
123 | @param outSegFunc SegmentFunction to call to output one physical segment. |
124 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
125 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
126 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
127 | @result Returns true if the inherited classes and this instance initialize |
128 | successfully. |
129 | */ |
130 | virtual bool initWithSpecification(SegmentFunction outSegFunc, |
131 | IOPhysicalLength maxSegmentSize = 0, |
132 | IOPhysicalLength maxTransferSize = 0, |
133 | IOPhysicalLength alignment = 1); |
134 | |
135 | /*! @function genPhysicalSegments |
136 | @abstract Generates a physical scatter/gather list given a memory descriptor. |
137 | @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. |
138 | @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. |
139 | @param fromPosition Starting location of the I/O within a memory descriptor. |
140 | @param segments Void pointer to base of output physical scatter/gather list. Always passed directly onto the SegmentFunction without interpretation by the cursor. |
141 | @param maxSegments Maximum number of segments that can be written to segments array. |
142 | @param maxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. |
143 | @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. |
144 | @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. |
145 | */ |
146 | virtual UInt32 genPhysicalSegments( |
147 | IOMemoryDescriptor *descriptor, |
148 | IOByteCount fromPosition, |
149 | void * segments, |
150 | UInt32 maxSegments, |
151 | UInt32 maxTransferSize = 0, |
152 | IOByteCount *transferSize = 0); |
153 | }; |
154 | |
155 | /************************ class IONaturalMemoryCursor ************************/ |
156 | |
157 | |
158 | /*! |
159 | @class IONaturalMemoryCursor |
160 | @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the natural byte orientation for the CPU. |
161 | @discussion The IONaturalMemoryCursor would be used when it is too difficult to safely describe a SegmentFunction that is more appropriate for your hardware. This cursor just outputs an array of PhysicalSegments. |
162 | */ |
163 | class IONaturalMemoryCursor : public IOMemoryCursor |
164 | { |
165 | OSDeclareDefaultStructors(IONaturalMemoryCursor) |
166 | |
167 | public: |
168 | /*! @function outputSegment |
169 | @abstract Outputs the given segment into the output segments array in natural byte order. |
170 | @param segment The physical address and length that is next to be output. |
171 | @param segments Base of the output vector of DMA address length pairs. |
172 | @param segmentIndex Index to output 'segment' in the 'segments' array. |
173 | */ |
174 | static void outputSegment(PhysicalSegment segment, |
175 | void * segments, |
176 | UInt32 segmentIndex); |
177 | |
178 | /*! @defined naturalOutputSegment |
179 | @discussion Backward compatibility define for the old global function definition. See IONaturalMemoryCursor::outputSegment. |
180 | */ |
181 | #define naturalOutputSegment IONaturalMemoryCursor::outputSegment |
182 | |
183 | /*! @function withSpecification |
184 | @abstract Creates and initializes an IONaturalMemoryCursor in one operation. |
185 | @discussion Factory function to create and initialize an IONaturalMemoryCursor in one operation. For more information, see IONaturalMemoryCursor::initWithSpecification. |
186 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
187 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
188 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
189 | @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. |
190 | */ |
191 | static IONaturalMemoryCursor * |
192 | withSpecification(IOPhysicalLength maxSegmentSize, |
193 | IOPhysicalLength maxTransferSize, |
194 | IOPhysicalLength alignment = 1); |
195 | |
196 | /*! @function initWithSpecification |
197 | @abstract Primary initializer for the IONaturalMemoryCursor class. |
198 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
199 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
200 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
201 | @result Returns true if the inherited classes and this instance initialize successfully. |
202 | */ |
203 | virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, |
204 | IOPhysicalLength maxTransferSize, |
205 | IOPhysicalLength alignment = 1); |
206 | |
207 | |
208 | /*! @function getPhysicalSegments |
209 | @abstract Generates a CPU natural physical scatter/gather list given a memory descriptor. |
210 | @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. |
211 | @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. |
212 | @param fromPosition Starting location of the I/O within a memory descriptor. |
213 | @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. |
214 | @param maxSegments Maximum number of segments that can be written to segments array. |
215 | @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. |
216 | @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. |
217 | @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. |
218 | */ |
219 | virtual UInt32 getPhysicalSegments(IOMemoryDescriptor *descriptor, |
220 | IOByteCount fromPosition, |
221 | PhysicalSegment *segments, |
222 | UInt32 maxSegments, |
223 | UInt32 inMaxTransferSize = 0, |
224 | IOByteCount *transferSize = 0) |
225 | { |
226 | return genPhysicalSegments(descriptor, fromPosition, segments, |
227 | maxSegments, inMaxTransferSize, transferSize); |
228 | } |
229 | }; |
230 | |
231 | /************************** class IOBigMemoryCursor **************************/ |
232 | |
233 | /*! |
234 | @class IOBigMemoryCursor |
235 | @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the big endian byte order. |
236 | @discussion The IOBigMemoryCursor would be used when the DMA hardware requires a big endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in big-endian format. |
237 | */ |
238 | class IOBigMemoryCursor : public IOMemoryCursor |
239 | { |
240 | OSDeclareDefaultStructors(IOBigMemoryCursor) |
241 | |
242 | public: |
243 | /*! @function outputSegment |
244 | @abstract Outputs the given segment into the output segments array in big endian byte order. |
245 | @param segment The physical address and length that is next to be output. |
246 | @param segments Base of the output vector of DMA address length pairs. |
247 | @param segmentIndex Index to output 'segment' in the 'segments' array. |
248 | */ |
249 | static void outputSegment(PhysicalSegment segment, |
250 | void * segments, |
251 | UInt32 segmentIndex); |
252 | |
253 | /*! @defined bigOutputSegment |
254 | @discussion Backward compatibility define for the old global function definition. See IOBigMemoryCursor::outputSegment |
255 | */ |
256 | #define bigOutputSegment IOBigMemoryCursor::outputSegment |
257 | |
258 | /*! @function withSpecification |
259 | @abstract Creates and initializes an IOBigMemoryCursor in one operation. |
260 | @discussion Factory function to create and initialize an IOBigMemoryCursor in one operation. See also IOBigMemoryCursor::initWithSpecification. |
261 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
262 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
263 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
264 | @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. |
265 | */ |
266 | static IOBigMemoryCursor * |
267 | withSpecification(IOPhysicalLength maxSegmentSize, |
268 | IOPhysicalLength maxTransferSize, |
269 | IOPhysicalLength alignment = 1); |
270 | |
271 | /*! @function initWithSpecification |
272 | @abstract Primary initializer for the IOBigMemoryCursor class. |
273 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
274 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
275 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
276 | @result Returns true if the inherited classes and this instance initialize |
277 | successfully. |
278 | */ |
279 | virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, |
280 | IOPhysicalLength maxTransferSize, |
281 | IOPhysicalLength alignment = 1); |
282 | |
283 | |
284 | /*! @function getPhysicalSegments |
285 | @abstract Generates a big endian physical scatter/gather list given a memory descriptor. |
286 | @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. |
287 | @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. |
288 | @param fromPosition Starting location of the I/O within a memory descriptor. |
289 | @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. |
290 | @param maxSegments Maximum number of segments that can be written to segments array. |
291 | @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. |
292 | @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. |
293 | @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. |
294 | */ |
295 | virtual UInt32 getPhysicalSegments(IOMemoryDescriptor * descriptor, |
296 | IOByteCount fromPosition, |
297 | PhysicalSegment * segments, |
298 | UInt32 maxSegments, |
299 | UInt32 inMaxTransferSize = 0, |
300 | IOByteCount * transferSize = 0) |
301 | { |
302 | return genPhysicalSegments(descriptor, fromPosition, segments, |
303 | maxSegments, inMaxTransferSize, transferSize); |
304 | } |
305 | }; |
306 | |
307 | /************************* class IOLittleMemoryCursor ************************/ |
308 | |
309 | /*! |
310 | @class IOLittleMemoryCursor |
311 | @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the little endian byte order. |
312 | @discussion The IOLittleMemoryCursor would be used when the DMA hardware requires a little endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in little endian format. |
313 | */ |
314 | class IOLittleMemoryCursor : public IOMemoryCursor |
315 | { |
316 | OSDeclareDefaultStructors(IOLittleMemoryCursor) |
317 | |
318 | public: |
319 | /*! @function outputSegment |
320 | @abstract Outputs the given segment into the output segments array in little endian byte order. |
321 | @param segment The physical address and length that is next to be output. |
322 | @param segments Base of the output vector of DMA address length pairs. |
323 | @param segmentIndex Index to output 'segment' in the 'segments' array. |
324 | */ |
325 | static void outputSegment(PhysicalSegment segment, |
326 | void * segments, |
327 | UInt32 segmentIndex); |
328 | |
329 | /*! @defined littleOutputSegment |
330 | @discussion Backward compatibility define for the old global function definition. See also IOLittleMemoryCursor::outputSegment. */ |
331 | #define littleOutputSegment IOLittleMemoryCursor::outputSegment |
332 | |
333 | /*! @function withSpecification |
334 | @abstract Creates and initializes an IOLittleMemoryCursor in one operation. |
335 | @discussion Factory function to create and initialize an IOLittleMemoryCursor in one operation. See also IOLittleMemoryCursor::initWithSpecification. |
336 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
337 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
338 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
339 | @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. |
340 | */ |
341 | static IOLittleMemoryCursor * |
342 | withSpecification(IOPhysicalLength maxSegmentSize, |
343 | IOPhysicalLength maxTransferSize, |
344 | IOPhysicalLength alignment = 1); |
345 | |
346 | /*! @function initWithSpecification |
347 | @abstract Primary initializer for the IOLittleMemoryCursor class. |
348 | @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. |
349 | @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. |
350 | @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. |
351 | @result Returns true if the inherited classes and this instance initialize successfully. |
352 | */ |
353 | virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, |
354 | IOPhysicalLength maxTransferSize, |
355 | IOPhysicalLength alignment = 1); |
356 | |
357 | |
358 | /*! @function getPhysicalSegments |
359 | @abstract Generates a little endian physical scatter/gather list given a memory descriptor. |
360 | @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. |
361 | @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. |
362 | @param fromPosition Starting location of the I/O within a memory descriptor. |
363 | @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. |
364 | @param maxSegments Maximum number of segments that can be written to segments array. |
365 | @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. |
366 | @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. |
367 | @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. |
368 | */ |
369 | virtual UInt32 getPhysicalSegments(IOMemoryDescriptor * descriptor, |
370 | IOByteCount fromPosition, |
371 | PhysicalSegment * segments, |
372 | UInt32 maxSegments, |
373 | UInt32 inMaxTransferSize = 0, |
374 | IOByteCount * transferSize = 0) |
375 | { |
376 | return genPhysicalSegments(descriptor, fromPosition, segments, |
377 | maxSegments, inMaxTransferSize, transferSize); |
378 | } |
379 | }; |
380 | |
381 | #endif /* !_IOMEMORYCURSOR_H */ |
382 | |
383 | |