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__) */