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
)
64 // @@@ gvdl: Remove me
66 static UInt sMaxDBDMASegment
;
67 if (!sMaxDBDMASegment
) {
68 sMaxDBDMASegment
= (UInt
) -1;
69 if (PE_parse_boot_arg("mseg", &sMaxDBDMASegment
))
70 IOLog("Setting MaxDBDMASegment to %d\n", sMaxDBDMASegment
);
73 if (inMaxSegmentSize
> sMaxDBDMASegment
) inMaxSegmentSize
= sMaxDBDMASegment
;
83 maxSegmentSize
= inMaxSegmentSize
;
84 if (inMaxTransferSize
)
85 maxTransferSize
= inMaxTransferSize
;
87 maxTransferSize
= (IOPhysicalLength
) -1;
88 alignMask
= inAlignment
- 1;
89 assert(alignMask
== 0); // No alignment code yet!
94 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
97 IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor
*inDescriptor
,
98 IOPhysicalLength fromPosition
,
100 UInt32 inMaxSegments
,
101 UInt32 inMaxTransferSize
,
102 IOByteCount
*outTransferSize
)
110 if (!inMaxTransferSize
)
111 inMaxTransferSize
= maxTransferSize
;
114 * Iterate over the packet, translating segments where allowed
116 * If we finished cleanly return number of segments found
117 * and update the position in the descriptor.
119 PhysicalSegment curSeg
= { 0, 0 };
120 UInt curSegIndex
= 0;
121 UInt curTransferSize
= 0;
122 IOByteCount inDescriptorLength
= inDescriptor
->getLength();
123 PhysicalSegment seg
= { 0, 0 };
125 while ((seg
.location
) || (fromPosition
< inDescriptorLength
))
129 seg
.location
= inDescriptor
->getPhysicalSegment(
130 fromPosition
, &seg
.length
);
131 assert(seg
.location
);
133 fromPosition
+= seg
.length
;
136 if (!curSeg
.location
)
138 curTransferSize
+= seg
.length
;
142 else if ((curSeg
.location
+ curSeg
.length
== seg
.location
))
144 curTransferSize
+= seg
.length
;
145 curSeg
.length
+= seg
.length
;
151 if ((curSeg
.length
> maxSegmentSize
))
153 seg
.location
= curSeg
.location
+ maxSegmentSize
;
154 seg
.length
= curSeg
.length
- maxSegmentSize
;
155 curTransferSize
-= seg
.length
;
156 curSeg
.length
-= seg
.length
;
159 if ((curTransferSize
>= inMaxTransferSize
))
161 curSeg
.length
-= curTransferSize
- inMaxTransferSize
;
162 curTransferSize
= inMaxTransferSize
;
169 if ((curSegIndex
+ 1 == inMaxSegments
))
171 (*outSeg
)(curSeg
, inSegments
, curSegIndex
++);
177 (*outSeg
)(curSeg
, inSegments
, curSegIndex
++);
180 *outTransferSize
= curTransferSize
;
185 /************************ class IONaturalMemoryCursor ************************/
188 #define super IOMemoryCursor
189 OSDefineMetaClassAndStructors(IONaturalMemoryCursor
, IOMemoryCursor
)
191 void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment
,
193 UInt32 outSegmentIndex
)
195 ((PhysicalSegment
*) outSegments
)[outSegmentIndex
] = segment
;
198 IONaturalMemoryCursor
*
199 IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
200 IOPhysicalLength inMaxTransferSize
,
201 IOPhysicalLength inAlignment
)
203 IONaturalMemoryCursor
*me
= new IONaturalMemoryCursor
;
205 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
217 IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
218 IOPhysicalLength inMaxTransferSize
,
219 IOPhysicalLength inAlignment
)
221 return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment
,
227 /************************** class IOBigMemoryCursor **************************/
230 #define super IOMemoryCursor
231 OSDefineMetaClassAndStructors(IOBigMemoryCursor
, IOMemoryCursor
)
234 IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment
,
236 UInt32 inSegmentIndex
)
238 IOPhysicalAddress
* segment
;
240 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
241 OSWriteBigInt(segment
, 0, inSegment
.location
);
242 OSWriteBigInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
246 IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
247 IOPhysicalLength inMaxTransferSize
,
248 IOPhysicalLength inAlignment
)
250 IOBigMemoryCursor
* me
= new IOBigMemoryCursor
;
252 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
264 IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
265 IOPhysicalLength inMaxTransferSize
,
266 IOPhysicalLength inAlignment
)
268 return super::initWithSpecification(&IOBigMemoryCursor::outputSegment
,
274 /************************* class IOLittleMemoryCursor ************************/
277 #define super IOMemoryCursor
278 OSDefineMetaClassAndStructors(IOLittleMemoryCursor
, IOMemoryCursor
)
281 IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment
,
283 UInt32 inSegmentIndex
)
285 IOPhysicalAddress
* segment
;
287 segment
= &((PhysicalSegment
*) inSegments
)[inSegmentIndex
].location
;
288 OSWriteLittleInt(segment
, 0, inSegment
.location
);
289 OSWriteLittleInt(segment
, sizeof(IOPhysicalAddress
), inSegment
.length
);
292 IOLittleMemoryCursor
*
293 IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
294 IOPhysicalLength inMaxTransferSize
,
295 IOPhysicalLength inAlignment
)
297 IOLittleMemoryCursor
* me
= new IOLittleMemoryCursor
;
299 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
310 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
313 IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
314 IOPhysicalLength inMaxTransferSize
,
315 IOPhysicalLength inAlignment
)
317 return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment
,
323 /************************* class IODBDMAMemoryCursor *************************/
327 #include <IOKit/ppc/IODBDMA.h>
330 #define super IOMemoryCursor
331 OSDefineMetaClassAndStructors(IODBDMAMemoryCursor
, IOMemoryCursor
)
334 IODBDMAMemoryCursor::outputSegment(PhysicalSegment inSegment
,
336 UInt32 inSegmentIndex
)
338 IODBDMADescriptor
*segment
;
340 segment
= &((IODBDMADescriptor
*) inSegments
)[inSegmentIndex
];
342 // Write location into address field
343 OSWriteSwapInt32((UInt32
*) segment
, 4, inSegment
.location
);
345 // Write count into 1st two bytes of operation field.
346 // DO NOT touch rest of operation field as it should contain a STOP command.
347 OSWriteSwapInt16((UInt16
*) segment
, 0, inSegment
.length
);
350 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
352 IODBDMAMemoryCursor
*
353 IODBDMAMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize
,
354 IOPhysicalLength inMaxTransferSize
,
355 IOPhysicalLength inAlignment
)
357 IODBDMAMemoryCursor
*me
= new IODBDMAMemoryCursor
;
359 if (me
&& !me
->initWithSpecification(inMaxSegmentSize
,
370 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
373 IODBDMAMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize
,
374 IOPhysicalLength inMaxTransferSize
,
375 IOPhysicalLength inAlignment
)
377 return super::initWithSpecification(&IODBDMAMemoryCursor::outputSegment
,
383 #endif /* defined(__ppc__) */