2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* IOMemoryCursor.cpp created by wgulland on 1999-3-02 */
27 #include <IOKit/assert.h>
28 #include <IOKit/IOLib.h>
29 #include <IOKit/IOMemoryCursor.h>
30 #include <IOKit/IOMemoryDescriptor.h>
31 #include <libkern/OSByteOrder.h>
33 /**************************** class IOMemoryCursor ***************************/
36 #define super OSObject
37 OSDefineMetaClassAndStructors(IOMemoryCursor
, OSObject
)
40 IOMemoryCursor::withSpecification(SegmentFunction inSegFunc
,
41 IOPhysicalLength inMaxSegmentSize
,
42 IOPhysicalLength inMaxTransferSize
,
43 IOPhysicalLength inAlignment
)
45 IOMemoryCursor
* me
= new IOMemoryCursor
;
47 if (me
&& !me
->initWithSpecification(inSegFunc
,
59 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
62 IOMemoryCursor::initWithSpecification(SegmentFunction inSegFunc
,
63 IOPhysicalLength inMaxSegmentSize
,
64 IOPhysicalLength inMaxTransferSize
,
65 IOPhysicalLength inAlignment
)
74 maxSegmentSize
= inMaxSegmentSize
;
75 if (inMaxTransferSize
)
76 maxTransferSize
= inMaxTransferSize
;
78 maxTransferSize
= (IOPhysicalLength
) -1;
79 alignMask
= inAlignment
- 1;
80 assert(alignMask
== 0); // No alignment code yet!
85 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
88 IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor
*inDescriptor
,
89 IOPhysicalLength fromPosition
,
92 UInt32 inMaxTransferSize
,
93 IOByteCount
*outTransferSize
)
101 if (!inMaxTransferSize
)
102 inMaxTransferSize
= maxTransferSize
;
105 * Iterate over the packet, translating segments where allowed
107 * If we finished cleanly return number of segments found
108 * and update the position in the descriptor.
110 UInt curSegIndex
= 0;
111 UInt curTransferSize
= 0;
114 while ((curSegIndex
< inMaxSegments
)
115 && (curTransferSize
< inMaxTransferSize
)
116 && (seg
.location
= inDescriptor
->getPhysicalSegment(
117 fromPosition
+ curTransferSize
, &seg
.length
)))
120 seg
.length
= min(inMaxTransferSize
-curTransferSize
,
121 (min(seg
.length
, maxSegmentSize
)));
122 (*outSeg
)(seg
, inSegments
, curSegIndex
++);
123 curTransferSize
+= seg
.length
;
127 *outTransferSize
= curTransferSize
;
132 /************************ class IONaturalMemoryCursor ************************/
135 #define super IOMemoryCursor
136 OSDefineMetaClassAndStructors(IONaturalMemoryCursor
, IOMemoryCursor
)
138 void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment
,
140 UInt32 outSegmentIndex
)
142 ((PhysicalSegment
*) outSegments
)[outSegmentIndex
] = segment
;
145 IONaturalMemoryCursor
*
146 IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
147 IOPhysicalLength inMaxTransferSize
,
148 IOPhysicalLength inAlignment
)
150 IONaturalMemoryCursor
*me
= new IONaturalMemoryCursor
;
152 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
164 IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
165 IOPhysicalLength inMaxTransferSize
,
166 IOPhysicalLength inAlignment
)
168 return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment
,
174 /************************** class IOBigMemoryCursor **************************/
177 #define super IOMemoryCursor
178 OSDefineMetaClassAndStructors(IOBigMemoryCursor
, IOMemoryCursor
)
181 IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment
,
183 UInt32 inSegmentIndex
)
185 IOPhysicalAddress
* segment
;
187 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
188 OSWriteBigInt(segment
, 0, inSegment
.location
);
189 OSWriteBigInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
193 IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
194 IOPhysicalLength inMaxTransferSize
,
195 IOPhysicalLength inAlignment
)
197 IOBigMemoryCursor
* me
= new IOBigMemoryCursor
;
199 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
211 IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
212 IOPhysicalLength inMaxTransferSize
,
213 IOPhysicalLength inAlignment
)
215 return super::initWithSpecification(&IOBigMemoryCursor::outputSegment
,
221 /************************* class IOLittleMemoryCursor ************************/
224 #define super IOMemoryCursor
225 OSDefineMetaClassAndStructors(IOLittleMemoryCursor
, IOMemoryCursor
)
228 IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment
,
230 UInt32 inSegmentIndex
)
232 IOPhysicalAddress
* segment
;
234 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
235 OSWriteLittleInt(segment
, 0, inSegment
.location
);
236 OSWriteLittleInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
239 IOLittleMemoryCursor
*
240 IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
241 IOPhysicalLength inMaxTransferSize
,
242 IOPhysicalLength inAlignment
)
244 IOLittleMemoryCursor
* me
= new IOLittleMemoryCursor
;
246 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
257 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
260 IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
261 IOPhysicalLength inMaxTransferSize
,
262 IOPhysicalLength inAlignment
)
264 return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment
,
270 /************************* class IODBDMAMemoryCursor *************************/
274 #include <IOKit/ppc/IODBDMA.h>
277 #define super IOMemoryCursor
278 OSDefineMetaClassAndStructors(IODBDMAMemoryCursor
, IOMemoryCursor
)
281 IODBDMAMemoryCursor::outputSegment(PhysicalSegment inSegment
,
283 UInt32 inSegmentIndex
)
285 IODBDMADescriptor
*segment
;
287 segment
= &((IODBDMADescriptor
*) inSegments
)[inSegmentIndex
];
289 // Write location into address field
290 OSWriteSwapInt32((UInt32
*) segment
, 4, inSegment
.location
);
292 // Write count into 1st two bytes of operation field.
293 // DO NOT touch rest of operation field as it should contain a STOP command.
294 OSWriteSwapInt16((UInt16
*) segment
, 0, inSegment
.length
);
297 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
299 IODBDMAMemoryCursor
*
300 IODBDMAMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
301 IOPhysicalLength inMaxTransferSize
,
302 IOPhysicalLength inAlignment
)
304 IODBDMAMemoryCursor
*me
= new IODBDMAMemoryCursor
;
306 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
317 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
320 IODBDMAMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
321 IOPhysicalLength inMaxTransferSize
,
322 IOPhysicalLength inAlignment
)
324 return super::initWithSpecification(&IODBDMAMemoryCursor::outputSegment
,
330 #endif /* defined(__ppc__) */