2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* IOMemoryCursor.cpp created by wgulland on 1999-3-02 */
24 #include <IOKit/assert.h>
25 #include <IOKit/IOLib.h>
26 #include <IOKit/IOMemoryCursor.h>
27 #include <IOKit/IOMemoryDescriptor.h>
28 #include <libkern/OSByteOrder.h>
30 /**************************** class IOMemoryCursor ***************************/
33 #define super OSObject
34 OSDefineMetaClassAndStructors(IOMemoryCursor
, OSObject
)
37 IOMemoryCursor::withSpecification(SegmentFunction inSegFunc
,
38 IOPhysicalLength inMaxSegmentSize
,
39 IOPhysicalLength inMaxTransferSize
,
40 IOPhysicalLength inAlignment
)
42 IOMemoryCursor
* me
= new IOMemoryCursor
;
44 if (me
&& !me
->initWithSpecification(inSegFunc
,
56 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
59 IOMemoryCursor::initWithSpecification(SegmentFunction inSegFunc
,
60 IOPhysicalLength inMaxSegmentSize
,
61 IOPhysicalLength inMaxTransferSize
,
62 IOPhysicalLength inAlignment
)
71 maxSegmentSize
= inMaxSegmentSize
;
72 if (inMaxTransferSize
)
73 maxTransferSize
= inMaxTransferSize
;
75 maxTransferSize
= (IOPhysicalLength
) -1;
76 alignMask
= inAlignment
- 1;
77 assert(alignMask
== 0); // No alignment code yet!
82 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
85 IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor
*inDescriptor
,
86 IOPhysicalLength fromPosition
,
89 UInt32 inMaxTransferSize
,
90 IOByteCount
*outTransferSize
)
98 if (!inMaxTransferSize
)
99 inMaxTransferSize
= maxTransferSize
;
102 * Iterate over the packet, translating segments where allowed
104 * If we finished cleanly return number of segments found
105 * and update the position in the descriptor.
107 UInt curSegIndex
= 0;
108 UInt curTransferSize
= 0;
111 while ((curSegIndex
< inMaxSegments
)
112 && (curTransferSize
< inMaxTransferSize
)
113 && (seg
.location
= inDescriptor
->getPhysicalSegment(
114 fromPosition
+ curTransferSize
, &seg
.length
)))
117 seg
.length
= min(inMaxTransferSize
-curTransferSize
,
118 (min(seg
.length
, maxSegmentSize
)));
119 (*outSeg
)(seg
, inSegments
, curSegIndex
++);
120 curTransferSize
+= seg
.length
;
124 *outTransferSize
= curTransferSize
;
129 /************************ class IONaturalMemoryCursor ************************/
132 #define super IOMemoryCursor
133 OSDefineMetaClassAndStructors(IONaturalMemoryCursor
, IOMemoryCursor
)
135 void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment
,
137 UInt32 outSegmentIndex
)
139 ((PhysicalSegment
*) outSegments
)[outSegmentIndex
] = segment
;
142 IONaturalMemoryCursor
*
143 IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
144 IOPhysicalLength inMaxTransferSize
,
145 IOPhysicalLength inAlignment
)
147 IONaturalMemoryCursor
*me
= new IONaturalMemoryCursor
;
149 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
161 IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
162 IOPhysicalLength inMaxTransferSize
,
163 IOPhysicalLength inAlignment
)
165 return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment
,
171 /************************** class IOBigMemoryCursor **************************/
174 #define super IOMemoryCursor
175 OSDefineMetaClassAndStructors(IOBigMemoryCursor
, IOMemoryCursor
)
178 IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment
,
180 UInt32 inSegmentIndex
)
182 IOPhysicalAddress
* segment
;
184 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
185 OSWriteBigInt(segment
, 0, inSegment
.location
);
186 OSWriteBigInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
190 IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
191 IOPhysicalLength inMaxTransferSize
,
192 IOPhysicalLength inAlignment
)
194 IOBigMemoryCursor
* me
= new IOBigMemoryCursor
;
196 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
208 IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
209 IOPhysicalLength inMaxTransferSize
,
210 IOPhysicalLength inAlignment
)
212 return super::initWithSpecification(&IOBigMemoryCursor::outputSegment
,
218 /************************* class IOLittleMemoryCursor ************************/
221 #define super IOMemoryCursor
222 OSDefineMetaClassAndStructors(IOLittleMemoryCursor
, IOMemoryCursor
)
225 IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment
,
227 UInt32 inSegmentIndex
)
229 IOPhysicalAddress
* segment
;
231 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
232 OSWriteLittleInt(segment
, 0, inSegment
.location
);
233 OSWriteLittleInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
236 IOLittleMemoryCursor
*
237 IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
238 IOPhysicalLength inMaxTransferSize
,
239 IOPhysicalLength inAlignment
)
241 IOLittleMemoryCursor
* me
= new IOLittleMemoryCursor
;
243 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
254 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
257 IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
258 IOPhysicalLength inMaxTransferSize
,
259 IOPhysicalLength inAlignment
)
261 return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment
,
267 /************************* class IODBDMAMemoryCursor *************************/
271 #include <IOKit/ppc/IODBDMA.h>
274 #define super IOMemoryCursor
275 OSDefineMetaClassAndStructors(IODBDMAMemoryCursor
, IOMemoryCursor
)
278 IODBDMAMemoryCursor::outputSegment(PhysicalSegment inSegment
,
280 UInt32 inSegmentIndex
)
282 IODBDMADescriptor
*segment
;
284 segment
= &((IODBDMADescriptor
*) inSegments
)[inSegmentIndex
];
286 // Write location into address field
287 OSWriteSwapInt32((UInt32
*) segment
, 4, inSegment
.location
);
289 // Write count into 1st two bytes of operation field.
290 // DO NOT touch rest of operation field as it should contain a STOP command.
291 OSWriteSwapInt16((UInt16
*) segment
, 0, inSegment
.length
);
294 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
296 IODBDMAMemoryCursor
*
297 IODBDMAMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
298 IOPhysicalLength inMaxTransferSize
,
299 IOPhysicalLength inAlignment
)
301 IODBDMAMemoryCursor
*me
= new IODBDMAMemoryCursor
;
303 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
314 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
317 IODBDMAMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
318 IOPhysicalLength inMaxTransferSize
,
319 IOPhysicalLength inAlignment
)
321 return super::initWithSpecification(&IODBDMAMemoryCursor::outputSegment
,
327 #endif /* defined(__ppc__) */