AppleRAIDStorageRequest.cpp [plain text]
#include "AppleRAID.h"
#define super IOCommand
OSDefineMetaClassAndStructors(AppleRAIDStorageRequest, IOCommand);
void AppleRAIDStorageRequest::free(void)
{
UInt32 index;
if (srRequestStatus != 0) IODelete(srRequestStatus, IOReturn, srRequestsAllocated);
if (srRequestByteCounts != 0) IODelete(srRequestByteCounts, UInt64, srRequestsAllocated);
if (srActiveMembers != 0) IODelete(srActiveMembers, AppleRAIDMember *, srMemberCount);
if (srMemoryDescriptors != 0) {
for (index = 0; index < srRequestsAllocated; index++) {
if (srMemoryDescriptors[index]) {
srMemoryDescriptors[index]->release();
}
}
IODelete(srMemoryDescriptors, AppleRAIDMemoryDescriptor *, srRequestsAllocated);
srMemoryDescriptors = 0;
}
super::free();
}
AppleRAIDStorageRequest *AppleRAIDStorageRequest::withAppleRAIDSet(AppleRAIDSet *set)
{
AppleRAIDStorageRequest *storageRequest = new AppleRAIDStorageRequest;
if (storageRequest != 0) {
if (!storageRequest->initWithAppleRAIDSet(set)) {
storageRequest->release();
storageRequest = 0;
}
}
return storageRequest;
}
bool AppleRAIDStorageRequest::initWithAppleRAIDSet(AppleRAIDSet *set)
{
UInt32 index;
if (!super::init()) return false;
srRAIDSet = set;
srEventSource = set->arSetEventSource;
srSetBlockSize = set->arMaxReadRequestFactor ? (set->arSetBlockSize * set->arMaxReadRequestFactor) : set->arSetBlockSize;
srMemberCount = set->getMemberCount();
srRequestCount = set->getMaxRequestCount();
srRequestsAllocated = set->getMaxRequestCount();
srMemberBaseOffset = set->getBase();
srRequestStatus = IONew(IOReturn, srRequestsAllocated);
if (srRequestStatus == 0) return false;
srRequestByteCounts = IONew(UInt64, srRequestsAllocated);
if (srRequestByteCounts == 0) return false;
srActiveMembers = IONew(AppleRAIDMember *, srMemberCount);
if (srActiveMembers == 0) return false;
srMemoryDescriptors = IONew(AppleRAIDMemoryDescriptor *, srRequestsAllocated);
if (srMemoryDescriptors == 0) return false;
for (index = 0; index < srRequestsAllocated; index++) {
srMemoryDescriptors[index] = set->allocateMemoryDescriptor(this, index);
if (!srMemoryDescriptors[index]) return false;
}
return true;
}
void AppleRAIDStorageRequest::extractRequest(IOService **client, UInt64 *byteStart,
IOMemoryDescriptor **buffer, IOStorageCompletion *completion)
{
*client = srClient;
*byteStart = srByteStart;
*buffer = srMemoryDescriptor;
*completion = srClientsCompletion;
}
void AppleRAIDStorageRequest::read(IOService *client, UInt64 byteStart, IOMemoryDescriptor *buffer,
IOStorageAttributes * attributes, IOStorageCompletion * completion)
{
UInt32 index, virtIndex;
AppleRAIDMember *member;
bool isOnline;
AppleRAIDMemoryDescriptor *memoryDescriptor;
IOStorageCompletion internalCompletion;
srClient = client;
srClientsCompletion = *completion;
srCompletedCount = 0;
srMemoryDescriptor = buffer;
srMemoryDescriptorDirection = buffer->getDirection();
srByteCount = buffer->getLength();
srByteStart = byteStart;
srRequestCount = srRAIDSet->getMaxRequestCount();
srActiveCount = srRAIDSet->getActiveCount();
srRAIDSet->activeReadMembers(srActiveMembers, srByteStart, srByteCount);
internalCompletion.target = srEventSource;
internalCompletion.action = srEventSource->getStorageCompletionAction();
for (virtIndex = 0; virtIndex < srMemberCount; virtIndex++) {
member = srActiveMembers[virtIndex];
isOnline = (uintptr_t)(member) >= 0x1000;
index = isOnline ? member->getMemberIndex() : (uintptr_t)member;
memoryDescriptor = srMemoryDescriptors[index];
if (isOnline && memoryDescriptor->configureForMemoryDescriptor(buffer, byteStart, virtIndex)) {
internalCompletion.parameter = memoryDescriptor;
member->read(srRAIDSet, srMemberBaseOffset + memoryDescriptor->mdMemberByteStart,
memoryDescriptor, attributes, &internalCompletion);
} else {
srEventSource->completeRequest(memoryDescriptor, kIOReturnSuccess, 0);
}
}
}
void AppleRAIDStorageRequest::write(IOService *client, UInt64 byteStart, IOMemoryDescriptor *buffer,
IOStorageAttributes * attributes, IOStorageCompletion * completion)
{
UInt32 index, virtIndex;
AppleRAIDMember *member;
bool isOnline;
AppleRAIDMemoryDescriptor *memoryDescriptor;
IOStorageCompletion internalCompletion;
srClient = client;
srClientsCompletion = *completion;
srCompletedCount = 0;
srMemoryDescriptor = buffer;
srMemoryDescriptorDirection = buffer->getDirection();
srByteCount = buffer->getLength();
srByteStart = byteStart;
srRequestCount = srRAIDSet->getMaxRequestCount();
srActiveCount = srRAIDSet->getActiveCount();
srRAIDSet->activeWriteMembers(srActiveMembers, srByteStart, srByteCount);
internalCompletion.target = srEventSource;
internalCompletion.action = srEventSource->getStorageCompletionAction();
for (virtIndex = 0; virtIndex < srMemberCount; virtIndex++) {
member = srActiveMembers[virtIndex];
isOnline = (uintptr_t)(member) >= 0x1000;
index = isOnline ? member->getMemberIndex() : (uintptr_t)member;
memoryDescriptor = srMemoryDescriptors[index];
if (isOnline && memoryDescriptor->configureForMemoryDescriptor(buffer, byteStart, virtIndex)) {
internalCompletion.parameter = memoryDescriptor;
member->write(srRAIDSet, srMemberBaseOffset + memoryDescriptor->mdMemberByteStart,
memoryDescriptor, attributes, &internalCompletion);
} else {
srEventSource->completeRequest(memoryDescriptor, kIOReturnSuccess, 0);
}
}
}