2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* IOMemoryCursor.cpp created by wgulland on 1999-3-02 */
30 #define IOKIT_ENABLE_SHARED_PTR
32 #include <IOKit/assert.h>
33 #include <IOKit/IOLib.h>
34 #include <IOKit/IOMemoryCursor.h>
35 #include <IOKit/IOMemoryDescriptor.h>
36 #include <libkern/OSByteOrder.h>
38 /**************************** class IOMemoryCursor ***************************/
41 #define super OSObject
42 OSDefineMetaClassAndStructors(IOMemoryCursor
, OSObject
)
44 OSSharedPtr
<IOMemoryCursor
>
45 IOMemoryCursor::withSpecification(SegmentFunction inSegFunc
,
46 IOPhysicalLength inMaxSegmentSize
,
47 IOPhysicalLength inMaxTransferSize
,
48 IOPhysicalLength inAlignment
)
50 OSSharedPtr
<IOMemoryCursor
> me
= OSMakeShared
<IOMemoryCursor
>();
52 if (me
&& !me
->initWithSpecification(inSegFunc
,
62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
65 IOMemoryCursor::initWithSpecification(SegmentFunction inSegFunc
,
66 IOPhysicalLength inMaxSegmentSize
,
67 IOPhysicalLength inMaxTransferSize
,
68 IOPhysicalLength inAlignment
)
70 // @@@ gvdl: Remove me
72 static UInt sMaxDBDMASegment
;
73 if (!sMaxDBDMASegment
) {
74 sMaxDBDMASegment
= (UInt
) - 1;
75 if (PE_parse_boot_argn("mseg", &sMaxDBDMASegment
, sizeof(sMaxDBDMASegment
))) {
76 IOLog("Setting MaxDBDMASegment to %d\n", sMaxDBDMASegment
);
80 if (inMaxSegmentSize
> sMaxDBDMASegment
) {
81 inMaxSegmentSize
= sMaxDBDMASegment
;
92 if (inMaxTransferSize
> UINT_MAX
) {
97 maxSegmentSize
= inMaxSegmentSize
;
98 if (inMaxTransferSize
) {
99 maxTransferSize
= inMaxTransferSize
;
101 maxTransferSize
= (IOPhysicalLength
) - 1;
103 alignMask
= inAlignment
- 1;
104 assert(alignMask
== 0); // No alignment code yet!
109 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
112 IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor
*inDescriptor
,
113 IOByteCount fromPosition
,
115 UInt32 inMaxSegments
,
116 UInt32 inMaxTransferSize
,
117 IOByteCount
*outTransferSize
)
123 if (!inMaxSegments
) {
127 if (!inMaxTransferSize
) {
128 inMaxTransferSize
= (typeof(inMaxTransferSize
))maxTransferSize
;
132 * Iterate over the packet, translating segments where allowed
134 * If we finished cleanly return number of segments found
135 * and update the position in the descriptor.
137 PhysicalSegment curSeg
= { 0, 0 };
138 UInt curSegIndex
= 0;
139 UInt curTransferSize
= 0;
140 IOByteCount inDescriptorLength
= inDescriptor
->getLength();
141 PhysicalSegment seg
= { 0, 0 };
143 while ((seg
.location
) || (fromPosition
< inDescriptorLength
)) {
145 seg
.location
= inDescriptor
->getPhysicalSegment(
146 fromPosition
, (IOByteCount
*)&seg
.length
);
147 assert(seg
.location
);
149 fromPosition
+= seg
.length
;
152 if (!curSeg
.location
) {
153 curTransferSize
+= seg
.length
;
156 } else if ((curSeg
.location
+ curSeg
.length
== seg
.location
)) {
157 curTransferSize
+= seg
.length
;
158 curSeg
.length
+= seg
.length
;
163 if ((curSeg
.length
> maxSegmentSize
)) {
164 seg
.location
= curSeg
.location
+ maxSegmentSize
;
165 seg
.length
= curSeg
.length
- maxSegmentSize
;
166 curTransferSize
-= seg
.length
;
167 curSeg
.length
-= seg
.length
;
170 if ((curTransferSize
>= inMaxTransferSize
)) {
171 curSeg
.length
-= curTransferSize
- inMaxTransferSize
;
172 curTransferSize
= inMaxTransferSize
;
178 if ((curSegIndex
+ 1 == inMaxSegments
)) {
181 (*outSeg
)(curSeg
, inSegments
, curSegIndex
++);
186 if (curSeg
.location
) {
187 (*outSeg
)(curSeg
, inSegments
, curSegIndex
++);
190 if (outTransferSize
) {
191 *outTransferSize
= curTransferSize
;
197 /************************ class IONaturalMemoryCursor ************************/
200 #define super IOMemoryCursor
201 OSDefineMetaClassAndStructors(IONaturalMemoryCursor
, IOMemoryCursor
)
204 IONaturalMemoryCursor::outputSegment(PhysicalSegment segment
,
206 UInt32 outSegmentIndex
)
208 ((PhysicalSegment
*) outSegments
)[outSegmentIndex
] = segment
;
211 OSSharedPtr
<IONaturalMemoryCursor
>
212 IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
213 IOPhysicalLength inMaxTransferSize
,
214 IOPhysicalLength inAlignment
)
216 OSSharedPtr
<IONaturalMemoryCursor
> me
= OSMakeShared
<IONaturalMemoryCursor
>();
218 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
228 IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
229 IOPhysicalLength inMaxTransferSize
,
230 IOPhysicalLength inAlignment
)
232 return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment
,
238 /************************** class IOBigMemoryCursor **************************/
241 #define super IOMemoryCursor
242 OSDefineMetaClassAndStructors(IOBigMemoryCursor
, IOMemoryCursor
)
245 IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment
,
247 UInt32 inSegmentIndex
)
249 IOPhysicalAddress
* segment
;
251 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
253 OSWriteBigInt64(segment
, 0, inSegment
.location
);
254 OSWriteBigInt64(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
256 OSWriteBigInt(segment
, 0, inSegment
.location
);
257 OSWriteBigInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
261 OSSharedPtr
<IOBigMemoryCursor
>
262 IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
263 IOPhysicalLength inMaxTransferSize
,
264 IOPhysicalLength inAlignment
)
266 OSSharedPtr
<IOBigMemoryCursor
> me
= OSMakeShared
<IOBigMemoryCursor
>();
268 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
278 IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
279 IOPhysicalLength inMaxTransferSize
,
280 IOPhysicalLength inAlignment
)
282 return super::initWithSpecification(&IOBigMemoryCursor::outputSegment
,
288 /************************* class IOLittleMemoryCursor ************************/
291 #define super IOMemoryCursor
292 OSDefineMetaClassAndStructors(IOLittleMemoryCursor
, IOMemoryCursor
)
295 IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment
,
297 UInt32 inSegmentIndex
)
299 IOPhysicalAddress
* segment
;
301 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
303 OSWriteLittleInt64(segment
, 0, inSegment
.location
);
304 OSWriteLittleInt64(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
306 OSWriteLittleInt(segment
, 0, inSegment
.location
);
307 OSWriteLittleInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
311 OSSharedPtr
<IOLittleMemoryCursor
>
312 IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
313 IOPhysicalLength inMaxTransferSize
,
314 IOPhysicalLength inAlignment
)
316 OSSharedPtr
<IOLittleMemoryCursor
> me
= OSMakeShared
<IOLittleMemoryCursor
>();
318 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
327 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
330 IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
331 IOPhysicalLength inMaxTransferSize
,
332 IOPhysicalLength inAlignment
)
334 return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment
,