1/* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 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. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 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. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28#ifndef _IOMEMORYCURSOR_H 29#define _IOMEMORYCURSOR_H 30 31#include <libkern/c++/OSObject.h> 32#include <IOKit/IOTypes.h> 33 34class IOMemoryDescriptor; 35 36/**************************** class IOMemoryCursor ***************************/ 37 38/*! 39 @class IOMemoryCursor 40 @abstract A mechanism to convert memory references to physical addresses. 41 @discussion The IOMemoryCursor declares the super class that all 42specific memory cursors must inherit from, but a memory cursor can be created without a specific format subclass by just providing a segment function to the initializers. This class does the difficult stuff of dividing a memory descriptor into a physical scatter/gather list appropriate for the target hardware. 43<br><br> 44 A driver is expected to create a memory cursor and configure it to the limitations of its DMA hardware; for instance the memory cursor used by the FireWire SBP-2 protocol has a maximum physical segment size of 2^16 - 1 but the actual transfer size is unlimited. Thus it would create a cursor with a maxSegmentSize of 65535 and a maxTransfer size of UINT_MAX. It would also provide a SegmentFunction that can output a pagelist entry. 45<br><br> 46Below is the simplest example of a SegmentFunction:<br> 47void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,<br> 48 void * outSegments,<br> 49 UInt32 outSegmentIndex)<br> 50{<br> 51 ((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;<br> 52} 53 54*/ 55class IOMemoryCursor : public OSObject 56{ 57 OSDeclareDefaultStructors(IOMemoryCursor) 58 59public: 60/*! 61 @typedef PhysicalSegment 62 @discussion A physical address/length pair. 63*/ 64 struct PhysicalSegment 65 { 66 IOPhysicalAddress location; 67 IOPhysicalLength length; 68 }; 69 70/*! @defined IOPhysicalSegment 71 @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::PhysicalSegment 72*/ 73#define IOPhysicalSegment IOMemoryCursor::PhysicalSegment 74 75/*! 76 @typedef SegmentFunction 77 @discussion Pointer to a C function that outputs a single physical segment to an element in the array as defined by the segments and segmentIndex parameters. 78 @param segment The physical address and length that is next to be output. 79 @param segments Base of the output vector of DMA address length pairs. 80 @param segmentIndex Index to output 'segment' in the 'segments' array. 81*/ 82 typedef void (*SegmentFunction)(PhysicalSegment segment, 83 void * segments, 84 UInt32 segmentIndex); 85 86/*! @defined OutputSegmentFunc 87 @discussion Backward compatibility define for the old non-class scoped type definition. See IOMemoryCursor::SegmentFunction */ 88#define OutputSegmentFunc IOMemoryCursor::SegmentFunction 89 90protected: 91/*! @var outSeg The action method called when an event has been delivered */ 92 SegmentFunction outSeg; 93 94/*! @var maxSegmentSize Maximum size of one segment in a scatter/gather list */ 95 IOPhysicalLength maxSegmentSize; 96 97/*! @var maxTransferSize 98 Maximum size of a transfer that this memory cursor is allowed to generate */ 99 IOPhysicalLength maxTransferSize; 100 101/*! @var alignMask 102 Currently unused. Reserved for automated aligment restriction code. */ 103 IOPhysicalLength alignMask; 104 105public: 106/*! @function withSpecification 107 @abstract Creates and initializes an IOMemoryCursor in one operation. 108 @discussion Factory function to create and initialize an IOMemoryCursor in one operation. For more information, see IOMemoryCursor::initWithSpecification. 109 @param outSegFunc SegmentFunction to call to output one physical segment. 110 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 111 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 112 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 113 @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. 114*/ 115 static IOMemoryCursor * 116 withSpecification(SegmentFunction outSegFunc, 117 IOPhysicalLength maxSegmentSize = 0, 118 IOPhysicalLength maxTransferSize = 0, 119 IOPhysicalLength alignment = 1); 120 121/*! @function initWithSpecification 122 @abstract Primary initializer for the IOMemoryCursor class. 123 @param outSegFunc SegmentFunction to call to output one physical segment. 124 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 125 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 126 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 127 @result Returns true if the inherited classes and this instance initialize 128successfully. 129*/ 130 virtual bool initWithSpecification(SegmentFunction outSegFunc, 131 IOPhysicalLength maxSegmentSize = 0, 132 IOPhysicalLength maxTransferSize = 0, 133 IOPhysicalLength alignment = 1); 134 135/*! @function genPhysicalSegments 136 @abstract Generates a physical scatter/gather list given a memory descriptor. 137 @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. 138 @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. 139 @param fromPosition Starting location of the I/O within a memory descriptor. 140 @param segments Void pointer to base of output physical scatter/gather list. Always passed directly onto the SegmentFunction without interpretation by the cursor. 141 @param maxSegments Maximum number of segments that can be written to segments array. 142 @param maxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. 143 @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. 144 @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. 145*/ 146 virtual UInt32 genPhysicalSegments( 147 IOMemoryDescriptor *descriptor, 148 IOByteCount fromPosition, 149 void * segments, 150 UInt32 maxSegments, 151 UInt32 maxTransferSize = 0, 152 IOByteCount *transferSize = 0); 153}; 154 155/************************ class IONaturalMemoryCursor ************************/ 156 157 158/*! 159 @class IONaturalMemoryCursor 160 @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the natural byte orientation for the CPU. 161 @discussion The IONaturalMemoryCursor would be used when it is too difficult to safely describe a SegmentFunction that is more appropriate for your hardware. This cursor just outputs an array of PhysicalSegments. 162*/ 163class IONaturalMemoryCursor : public IOMemoryCursor 164{ 165 OSDeclareDefaultStructors(IONaturalMemoryCursor) 166 167public: 168/*! @function outputSegment 169 @abstract Outputs the given segment into the output segments array in natural byte order. 170 @param segment The physical address and length that is next to be output. 171 @param segments Base of the output vector of DMA address length pairs. 172 @param segmentIndex Index to output 'segment' in the 'segments' array. 173*/ 174 static void outputSegment(PhysicalSegment segment, 175 void * segments, 176 UInt32 segmentIndex); 177 178/*! @defined naturalOutputSegment 179 @discussion Backward compatibility define for the old global function definition. See IONaturalMemoryCursor::outputSegment. 180*/ 181#define naturalOutputSegment IONaturalMemoryCursor::outputSegment 182 183/*! @function withSpecification 184 @abstract Creates and initializes an IONaturalMemoryCursor in one operation. 185 @discussion Factory function to create and initialize an IONaturalMemoryCursor in one operation. For more information, see IONaturalMemoryCursor::initWithSpecification. 186 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 187 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 188 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 189 @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. 190*/ 191 static IONaturalMemoryCursor * 192 withSpecification(IOPhysicalLength maxSegmentSize, 193 IOPhysicalLength maxTransferSize, 194 IOPhysicalLength alignment = 1); 195 196/*! @function initWithSpecification 197 @abstract Primary initializer for the IONaturalMemoryCursor class. 198 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 199 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 200 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 201 @result Returns true if the inherited classes and this instance initialize successfully. 202*/ 203 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, 204 IOPhysicalLength maxTransferSize, 205 IOPhysicalLength alignment = 1); 206 207 208/*! @function getPhysicalSegments 209 @abstract Generates a CPU natural physical scatter/gather list given a memory descriptor. 210 @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. 211 @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. 212 @param fromPosition Starting location of the I/O within a memory descriptor. 213 @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. 214 @param maxSegments Maximum number of segments that can be written to segments array. 215 @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. 216 @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. 217 @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. 218*/ 219 virtual UInt32 getPhysicalSegments(IOMemoryDescriptor *descriptor, 220 IOByteCount fromPosition, 221 PhysicalSegment *segments, 222 UInt32 maxSegments, 223 UInt32 inMaxTransferSize = 0, 224 IOByteCount *transferSize = 0) 225 { 226 return genPhysicalSegments(descriptor, fromPosition, segments, 227 maxSegments, inMaxTransferSize, transferSize); 228 } 229}; 230 231/************************** class IOBigMemoryCursor **************************/ 232 233/*! 234 @class IOBigMemoryCursor 235 @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the big endian byte order. 236 @discussion The IOBigMemoryCursor would be used when the DMA hardware requires a big endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in big-endian format. 237*/ 238class IOBigMemoryCursor : public IOMemoryCursor 239{ 240 OSDeclareDefaultStructors(IOBigMemoryCursor) 241 242public: 243/*! @function outputSegment 244 @abstract Outputs the given segment into the output segments array in big endian byte order. 245 @param segment The physical address and length that is next to be output. 246 @param segments Base of the output vector of DMA address length pairs. 247 @param segmentIndex Index to output 'segment' in the 'segments' array. 248*/ 249 static void outputSegment(PhysicalSegment segment, 250 void * segments, 251 UInt32 segmentIndex); 252 253/*! @defined bigOutputSegment 254 @discussion Backward compatibility define for the old global function definition. See IOBigMemoryCursor::outputSegment 255*/ 256#define bigOutputSegment IOBigMemoryCursor::outputSegment 257 258/*! @function withSpecification 259 @abstract Creates and initializes an IOBigMemoryCursor in one operation. 260 @discussion Factory function to create and initialize an IOBigMemoryCursor in one operation. See also IOBigMemoryCursor::initWithSpecification. 261 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 262 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 263 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 264 @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. 265*/ 266 static IOBigMemoryCursor * 267 withSpecification(IOPhysicalLength maxSegmentSize, 268 IOPhysicalLength maxTransferSize, 269 IOPhysicalLength alignment = 1); 270 271/*! @function initWithSpecification 272 @abstract Primary initializer for the IOBigMemoryCursor class. 273 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 274 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 275 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 276 @result Returns true if the inherited classes and this instance initialize 277successfully. 278*/ 279 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, 280 IOPhysicalLength maxTransferSize, 281 IOPhysicalLength alignment = 1); 282 283 284/*! @function getPhysicalSegments 285 @abstract Generates a big endian physical scatter/gather list given a memory descriptor. 286 @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. 287 @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. 288 @param fromPosition Starting location of the I/O within a memory descriptor. 289 @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. 290 @param maxSegments Maximum number of segments that can be written to segments array. 291 @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. 292 @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. 293 @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. 294*/ 295 virtual UInt32 getPhysicalSegments(IOMemoryDescriptor * descriptor, 296 IOByteCount fromPosition, 297 PhysicalSegment * segments, 298 UInt32 maxSegments, 299 UInt32 inMaxTransferSize = 0, 300 IOByteCount * transferSize = 0) 301 { 302 return genPhysicalSegments(descriptor, fromPosition, segments, 303 maxSegments, inMaxTransferSize, transferSize); 304 } 305}; 306 307/************************* class IOLittleMemoryCursor ************************/ 308 309/*! 310 @class IOLittleMemoryCursor 311 @abstract An IOMemoryCursor subclass that outputs a vector of PhysicalSegments in the little endian byte order. 312 @discussion The IOLittleMemoryCursor would be used when the DMA hardware requires a little endian address and length pair. This cursor outputs an array of PhysicalSegments that are encoded in little endian format. 313*/ 314class IOLittleMemoryCursor : public IOMemoryCursor 315{ 316 OSDeclareDefaultStructors(IOLittleMemoryCursor) 317 318public: 319/*! @function outputSegment 320 @abstract Outputs the given segment into the output segments array in little endian byte order. 321 @param segment The physical address and length that is next to be output. 322 @param segments Base of the output vector of DMA address length pairs. 323 @param segmentIndex Index to output 'segment' in the 'segments' array. 324*/ 325 static void outputSegment(PhysicalSegment segment, 326 void * segments, 327 UInt32 segmentIndex); 328 329/*! @defined littleOutputSegment 330 @discussion Backward compatibility define for the old global function definition. See also IOLittleMemoryCursor::outputSegment. */ 331#define littleOutputSegment IOLittleMemoryCursor::outputSegment 332 333/*! @function withSpecification 334 @abstract Creates and initializes an IOLittleMemoryCursor in one operation. 335 @discussion Factory function to create and initialize an IOLittleMemoryCursor in one operation. See also IOLittleMemoryCursor::initWithSpecification. 336 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 337 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 338 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 339 @result Returns a new memory cursor if successfully created and initialized, 0 otherwise. 340*/ 341 static IOLittleMemoryCursor * 342 withSpecification(IOPhysicalLength maxSegmentSize, 343 IOPhysicalLength maxTransferSize, 344 IOPhysicalLength alignment = 1); 345 346/*! @function initWithSpecification 347 @abstract Primary initializer for the IOLittleMemoryCursor class. 348 @param maxSegmentSize Maximum allowable size for one segment. Defaults to 0. 349 @param maxTransferSize Maximum size of an entire transfer. Defaults to 0 indicating no maximum. 350 @param alignment Alignment restrictions on output physical addresses. Not currently implemented. Defaults to single byte alignment. 351 @result Returns true if the inherited classes and this instance initialize successfully. 352*/ 353 virtual bool initWithSpecification(IOPhysicalLength maxSegmentSize, 354 IOPhysicalLength maxTransferSize, 355 IOPhysicalLength alignment = 1); 356 357 358/*! @function getPhysicalSegments 359 @abstract Generates a little endian physical scatter/gather list given a memory descriptor. 360 @discussion Generates a list of physical segments from the given memory descriptor, relative to the current position of the descriptor. Wraps IOMemoryCursor::genPhysicalSegments. 361 @param descriptor IOMemoryDescriptor that describes the data associated with an I/O request. 362 @param fromPosition Starting location of the I/O within a memory descriptor. 363 @param segments Pointer to an array of IOMemoryCursor::PhysicalSegments for the output physical scatter/gather list. 364 @param maxSegments Maximum number of segments that can be written to segments array. 365 @param inMaxTransferSize Maximum transfer size is limited to that many bytes, otherwise it defaults to the maximum transfer size specified when the memory cursor was initialized. 366 @param transferSize Pointer to an IOByteCount variable that can contain the total size of the transfer being described. Defaults to 0 indicating that no transfer size need be returned. 367 @result If the descriptor is exhausted of memory, a zero is returned, otherwise the number of segments that were filled in is returned. 368*/ 369 virtual UInt32 getPhysicalSegments(IOMemoryDescriptor * descriptor, 370 IOByteCount fromPosition, 371 PhysicalSegment * segments, 372 UInt32 maxSegments, 373 UInt32 inMaxTransferSize = 0, 374 IOByteCount * transferSize = 0) 375 { 376 return genPhysicalSegments(descriptor, fromPosition, segments, 377 maxSegments, inMaxTransferSize, transferSize); 378 } 379}; 380 381#endif /* !_IOMEMORYCURSOR_H */ 382 383