AppleRAIDStripeSet.cpp [plain text]
#include "AppleRAID.h"
#define super AppleRAIDSet
OSDefineMetaClassAndStructors(AppleRAIDStripeSet, AppleRAIDSet);
AppleRAIDSet * AppleRAIDStripeSet::createRAIDSet(AppleRAIDMember * firstMember)
{
AppleRAIDStripeSet *raidSet = new AppleRAIDStripeSet;
IOLog1("AppleRAIDStripeSet::createRAIDSet(%p) called, new set = %p *********\n", firstMember, raidSet);
while (raidSet){
if (!raidSet->init()) break;
if (!raidSet->initWithHeader(firstMember->getHeader(), true)) break;
if (raidSet->resizeSet(raidSet->getMemberCount())) return raidSet;
break;
}
if (raidSet) raidSet->release();
return 0;
}
bool AppleRAIDStripeSet::init()
{
IOLog1("AppleRAIDStripeSet::init() called\n");
if (super::init() == false) return false;
setProperty(kAppleRAIDLevelNameKey, kAppleRAIDLevelNameStripe);
arAllocateRequestMethod = OSMemberFunctionCast(IOCommandGate::Action, this, &AppleRAIDSet::allocateRAIDRequest);
return true;
}
void AppleRAIDStripeSet::free(void)
{
super::free();
}
bool AppleRAIDStripeSet::addSpare(AppleRAIDMember * member)
{
if (super::addSpare(member) == false) return false;
member->changeMemberState(kAppleRAIDMemberStateBroken);
return true;
}
bool AppleRAIDStripeSet::addMember(AppleRAIDMember * member)
{
if (super::addMember(member) == false) return false;
OSNumber * number = OSDynamicCast(OSNumber, member->getHeaderProperty(kAppleRAIDChunkCountKey));
if (!number) return false;
arSetBlockCount = number->unsigned64BitValue() * arMemberCount;
arSetMediaSize = arSetBlockCount * arSetBlockSize;
return true;
}
bool AppleRAIDStripeSet::startSet(void)
{
if (super::startSet() == false) return false;
setSmallest64BitMemberPropertyFor(kIOMaximumBlockCountReadKey, arMemberCount);
setSmallest64BitMemberPropertyFor(kIOMaximumBlockCountWriteKey, arMemberCount);
setSmallest64BitMemberPropertyFor(kIOMaximumByteCountReadKey, arMemberCount);
setSmallest64BitMemberPropertyFor(kIOMaximumByteCountWriteKey, arMemberCount);
setSmallest64BitMemberPropertyFor(kIOMaximumSegmentCountReadKey, arMemberCount);
setSmallest64BitMemberPropertyFor(kIOMaximumSegmentCountWriteKey, arMemberCount);
return true;
}
AppleRAIDMemoryDescriptor * AppleRAIDStripeSet::allocateMemoryDescriptor(AppleRAIDStorageRequest *storageRequest, UInt32 memberIndex)
{
return AppleRAIDStripeMemoryDescriptor::withStorageRequest(storageRequest, memberIndex);
}
#undef super
#define super AppleRAIDMemoryDescriptor
OSDefineMetaClassAndStructors(AppleRAIDStripeMemoryDescriptor, AppleRAIDMemoryDescriptor);
AppleRAIDMemoryDescriptor *
AppleRAIDStripeMemoryDescriptor::withStorageRequest(AppleRAIDStorageRequest *storageRequest, UInt32 memberIndex)
{
AppleRAIDMemoryDescriptor *memoryDescriptor = new AppleRAIDStripeMemoryDescriptor;
if (memoryDescriptor != 0) {
if (!memoryDescriptor->initWithStorageRequest(storageRequest, memberIndex)) {
memoryDescriptor->release();
memoryDescriptor = 0;
}
}
return memoryDescriptor;
}
bool AppleRAIDStripeMemoryDescriptor::initWithStorageRequest(AppleRAIDStorageRequest *storageRequest, UInt32 memberIndex)
{
if (!super::initWithStorageRequest(storageRequest, memberIndex)) return false;
mdMemberCount = storageRequest->srMemberCount;
mdSetBlockSize = storageRequest->srSetBlockSize;
return true;
}
bool AppleRAIDStripeMemoryDescriptor::configureForMemoryDescriptor(IOMemoryDescriptor *memoryDescriptor, UInt64 byteStart, UInt32 activeIndex)
{
UInt32 byteCount = memoryDescriptor->getLength();
UInt32 blockCount, memberBlockCount;
UInt64 memberBlockStart, setBlockStop;
UInt32 setBlockEndOffset;
UInt32 startMember, stopMember;
mdSetBlockStart = byteStart / mdSetBlockSize;
mdSetBlockOffset = byteStart % mdSetBlockSize;
setBlockStop = (byteStart + byteCount - 1) / mdSetBlockSize;
setBlockEndOffset = (byteStart + byteCount - 1) % mdSetBlockSize;
blockCount = setBlockStop - mdSetBlockStart + 1;
memberBlockCount = blockCount / mdMemberCount;
memberBlockStart = mdSetBlockStart / mdMemberCount;
startMember = mdSetBlockStart % mdMemberCount;
stopMember = setBlockStop % mdMemberCount;
assert(mdMemberIndex == activeIndex);
if (((mdMemberCount + mdMemberIndex - startMember) % mdMemberCount) < (blockCount % mdMemberCount)) memberBlockCount++;
if (startMember > mdMemberIndex) memberBlockStart++;
mdMemberByteStart = memberBlockStart * mdSetBlockSize;
_length = memberBlockCount * mdSetBlockSize;
if (startMember == mdMemberIndex) {
mdMemberByteStart += mdSetBlockOffset;
_length -= mdSetBlockOffset;
}
if (stopMember == mdMemberIndex) _length -= mdSetBlockSize - setBlockEndOffset - 1;
mdMemoryDescriptor = memoryDescriptor;
_direction = memoryDescriptor->getDirection();
return _length != 0;
}
IOPhysicalAddress AppleRAIDStripeMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount *length)
{
UInt32 memberBlockStart = (mdMemberByteStart + offset) / mdSetBlockSize;
UInt32 memberBlockOffset = (mdMemberByteStart + offset) % mdSetBlockSize;
UInt32 setBlockNumber = memberBlockStart * mdMemberCount + mdMemberIndex - mdSetBlockStart;
IOByteCount setOffset = setBlockNumber * mdSetBlockSize + memberBlockOffset - mdSetBlockOffset;
IOPhysicalAddress physAddress;
physAddress = mdMemoryDescriptor->getPhysicalSegment(setOffset, length);
memberBlockOffset = mdSetBlockSize - memberBlockOffset;
if (length && (*length > memberBlockOffset)) *length = memberBlockOffset;
return physAddress;
}
addr64_t AppleRAIDStripeMemoryDescriptor::getPhysicalSegment64(IOByteCount offset, IOByteCount *length)
{
UInt32 memberBlockStart = (mdMemberByteStart + offset) / mdSetBlockSize;
UInt32 memberBlockOffset = (mdMemberByteStart + offset) % mdSetBlockSize;
UInt32 setBlockNumber = memberBlockStart * mdMemberCount + mdMemberIndex - mdSetBlockStart;
IOByteCount setOffset = setBlockNumber * mdSetBlockSize + memberBlockOffset - mdSetBlockOffset;
addr64_t physAddress;
physAddress = mdMemoryDescriptor->getPhysicalSegment64(setOffset, length);
memberBlockOffset = mdSetBlockSize - memberBlockOffset;
if (length && (*length > memberBlockOffset)) *length = memberBlockOffset;
return physAddress;
}