AppleRAIDEventSource.cpp [plain text]
#include "AppleRAIDEventSource.h"
#undef super
#define super IOEventSource
OSDefineMetaClassAndStructors(AppleRAIDEventSource, IOEventSource);
AppleRAIDEventSource *AppleRAIDEventSource::withAppleRAIDSet(AppleRAID *appleRAID, Action action)
{
AppleRAIDEventSource *eventSource = new AppleRAIDEventSource;
if (eventSource != 0) {
if (!eventSource->initWithAppleRAIDSet(appleRAID, action)) {
eventSource->release();
eventSource = 0;
}
}
return eventSource;
}
bool AppleRAIDEventSource::initWithAppleRAIDSet(AppleRAID *appleRAID, Action action)
{
if (!super::init(appleRAID, (IOEventSource::Action)action)) return false;
queue_init(&fCompletedHead);
return true;
}
void AppleRAIDEventSource::sliceCompleteRequest(AppleRAIDMemoryDescriptor *memoryDescriptor,
IOReturn status, UInt64 actualByteCount)
{
UInt32 sliceNumber = memoryDescriptor->mdSliceNumber;
AppleRAIDStorageRequest *storageRequest = memoryDescriptor->mdStorageRequest;
closeGate();
storageRequest->srCompletedCount++;
storageRequest->srSliceStatus[sliceNumber] = status;
storageRequest->srSliceByteCounts[sliceNumber] = actualByteCount;
if (storageRequest->srCompletedCount == storageRequest->srSliceCount) {
queue_enter(&fCompletedHead, storageRequest, AppleRAIDStorageRequest *, fCommandChain);
signalWorkAvailable();
}
openGate();
}
void AppleRAIDEventSource::terminateRAIDMedia(IOMedia *media)
{
closeGate();
while (doTerminateRAIDMedia != 0) {
sleepGate(&doTerminateRAIDMedia, THREAD_UNINT);
}
doTerminateRAIDMedia = media;
doTerminateRAIDMedia->retain();
signalWorkAvailable();
openGate();
}
bool AppleRAIDEventSource::checkForWork(void)
{
AppleRAID *appleRAID = (AppleRAID *)owner;
AppleRAIDStorageRequest *storageRequest;
if (doTerminateRAIDMedia != 0) {
appleRAID->terminateRAIDMedia(doTerminateRAIDMedia);
doTerminateRAIDMedia->release();
doTerminateRAIDMedia = 0;
wakeupGate(&doTerminateRAIDMedia, true);
}
if (!queue_empty(&fCompletedHead)) {
queue_remove_first(&fCompletedHead, storageRequest, AppleRAIDStorageRequest *, fCommandChain);
(*(Action)action)(appleRAID, storageRequest);
}
return !queue_empty(&fCompletedHead);
}
IOStorageCompletionAction AppleRAIDEventSource::getStorageCompletionAction(void)
{
return (IOStorageCompletionAction)&AppleRAIDEventSource::sliceCompleteRequest;
}