IOMemoryCursor.cpp [plain text]
#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOMemoryCursor.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <libkern/OSByteOrder.h>
#undef super
#define super OSObject
OSDefineMetaClassAndStructors(IOMemoryCursor, OSObject)
IOMemoryCursor *
IOMemoryCursor::withSpecification(SegmentFunction inSegFunc,
IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
IOMemoryCursor * me = new IOMemoryCursor;
if (me && !me->initWithSpecification(inSegFunc,
inMaxSegmentSize,
inMaxTransferSize,
inAlignment))
{
me->release();
return 0;
}
return me;
}
bool
IOMemoryCursor::initWithSpecification(SegmentFunction inSegFunc,
IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
if (!super::init())
return false;
if (!inSegFunc)
return false;
outSeg = inSegFunc;
maxSegmentSize = inMaxSegmentSize;
if (inMaxTransferSize)
maxTransferSize = inMaxTransferSize;
else
maxTransferSize = (IOPhysicalLength) -1;
alignMask = inAlignment - 1;
assert(alignMask == 0);
return true;
}
UInt32
IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor *inDescriptor,
IOPhysicalLength fromPosition,
void * inSegments,
UInt32 inMaxSegments,
UInt32 inMaxTransferSize,
IOByteCount *outTransferSize)
{
if (!inDescriptor)
return 0;
if (!inMaxSegments)
return 0;
if (!inMaxTransferSize)
inMaxTransferSize = maxTransferSize;
UInt curSegIndex = 0;
UInt curTransferSize = 0;
PhysicalSegment seg;
while ((curSegIndex < inMaxSegments)
&& (curTransferSize < inMaxTransferSize)
&& (seg.location = inDescriptor->getPhysicalSegment(
fromPosition + curTransferSize, &seg.length)))
{
assert(seg.length);
seg.length = min(inMaxTransferSize-curTransferSize,
(min(seg.length, maxSegmentSize)));
(*outSeg)(seg, inSegments, curSegIndex++);
curTransferSize += seg.length;
}
if (outTransferSize)
*outTransferSize = curTransferSize;
return curSegIndex;
}
#undef super
#define super IOMemoryCursor
OSDefineMetaClassAndStructors(IONaturalMemoryCursor, IOMemoryCursor)
void IONaturalMemoryCursor::outputSegment(PhysicalSegment segment,
void * outSegments,
UInt32 outSegmentIndex)
{
((PhysicalSegment *) outSegments)[outSegmentIndex] = segment;
}
IONaturalMemoryCursor *
IONaturalMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
IONaturalMemoryCursor *me = new IONaturalMemoryCursor;
if (me && !me->initWithSpecification(inMaxSegmentSize,
inMaxTransferSize,
inAlignment))
{
me->release();
return 0;
}
return me;
}
bool
IONaturalMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
return super::initWithSpecification(&IONaturalMemoryCursor::outputSegment,
inMaxSegmentSize,
inMaxTransferSize,
inAlignment);
}
#undef super
#define super IOMemoryCursor
OSDefineMetaClassAndStructors(IOBigMemoryCursor, IOMemoryCursor)
void
IOBigMemoryCursor::outputSegment(PhysicalSegment inSegment,
void * inSegments,
UInt32 inSegmentIndex)
{
IOPhysicalAddress * segment;
segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
OSWriteBigInt(segment, 0, inSegment.location);
OSWriteBigInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
}
IOBigMemoryCursor *
IOBigMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
IOBigMemoryCursor * me = new IOBigMemoryCursor;
if (me && !me->initWithSpecification(inMaxSegmentSize,
inMaxTransferSize,
inAlignment))
{
me->release();
return 0;
}
return me;
}
bool
IOBigMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
return super::initWithSpecification(&IOBigMemoryCursor::outputSegment,
inMaxSegmentSize,
inMaxTransferSize,
inAlignment);
}
#undef super
#define super IOMemoryCursor
OSDefineMetaClassAndStructors(IOLittleMemoryCursor, IOMemoryCursor)
void
IOLittleMemoryCursor::outputSegment(PhysicalSegment inSegment,
void * inSegments,
UInt32 inSegmentIndex)
{
IOPhysicalAddress * segment;
segment = &((PhysicalSegment *) inSegments)[inSegmentIndex].location;
OSWriteLittleInt(segment, 0, inSegment.location);
OSWriteLittleInt(segment, sizeof(IOPhysicalAddress), inSegment.length);
}
IOLittleMemoryCursor *
IOLittleMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
IOLittleMemoryCursor * me = new IOLittleMemoryCursor;
if (me && !me->initWithSpecification(inMaxSegmentSize,
inMaxTransferSize,
inAlignment))
{
me->release();
return 0;
}
return me;
}
bool
IOLittleMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
return super::initWithSpecification(&IOLittleMemoryCursor::outputSegment,
inMaxSegmentSize,
inMaxTransferSize,
inAlignment);
}
#if defined(__ppc__)
#include <IOKit/ppc/IODBDMA.h>
#undef super
#define super IOMemoryCursor
OSDefineMetaClassAndStructors(IODBDMAMemoryCursor, IOMemoryCursor)
void
IODBDMAMemoryCursor::outputSegment(PhysicalSegment inSegment,
void * inSegments,
UInt32 inSegmentIndex)
{
IODBDMADescriptor *segment;
segment = &((IODBDMADescriptor *) inSegments)[inSegmentIndex];
OSWriteSwapInt32((UInt32 *) segment, 4, inSegment.location);
OSWriteSwapInt16((UInt16 *) segment, 0, inSegment.length);
}
IODBDMAMemoryCursor *
IODBDMAMemoryCursor::withSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
IODBDMAMemoryCursor *me = new IODBDMAMemoryCursor;
if (me && !me->initWithSpecification(inMaxSegmentSize,
inMaxTransferSize,
inAlignment))
{
me->release();
return 0;
}
return me;
}
bool
IODBDMAMemoryCursor::initWithSpecification(IOPhysicalLength inMaxSegmentSize,
IOPhysicalLength inMaxTransferSize,
IOPhysicalLength inAlignment)
{
return super::initWithSpecification(&IODBDMAMemoryCursor::outputSegment,
inMaxSegmentSize,
inMaxTransferSize,
inAlignment);
}
#endif