1/*
2 * Copyright (c) 2001-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#include "AppleRAID.h"
24
25#undef super
26#define super IOEventSource
27OSDefineMetaClassAndStructors(AppleRAIDEventSource, IOEventSource);
28
29AppleRAIDEventSource *AppleRAIDEventSource::withAppleRAIDSet(AppleRAIDSet *appleRAID, Action action)
30{
31    AppleRAIDEventSource *eventSource = new AppleRAIDEventSource;
32
33    if (eventSource != 0) {
34        if (!eventSource->initWithAppleRAIDSet(appleRAID, action)) {
35            eventSource->release();
36            eventSource = 0;
37        }
38    }
39
40    return eventSource;
41}
42
43bool AppleRAIDEventSource::initWithAppleRAIDSet(AppleRAIDSet *appleRAID, Action action)
44{
45    if (!super::init(appleRAID, (IOEventSource::Action)action)) return false;
46
47    queue_init(&fCompletedHead);
48
49    return true;
50}
51
52void AppleRAIDEventSource::completeRequest(AppleRAIDMemoryDescriptor * memoryDescriptor,
53					   IOReturn status, UInt64 actualByteCount)
54{
55    UInt32			memberIndex = memoryDescriptor->mdMemberIndex;
56    AppleRAIDStorageRequest *	storageRequest = memoryDescriptor->mdStorageRequest;
57
58    closeGate();
59
60    // Count the member as completed.
61    storageRequest->srCompletedCount++;
62
63    // Save the members results.
64    storageRequest->srRequestStatus[memberIndex] = status;
65    storageRequest->srRequestByteCounts[memberIndex] = actualByteCount;
66
67    if (storageRequest->srCompletedCount == storageRequest->srRequestCount) {
68        queue_enter(&fCompletedHead, storageRequest, AppleRAIDStorageRequest *, fCommandChain);
69
70	signalWorkAvailable();
71    }
72
73    openGate();
74}
75
76
77void AppleRAIDEventSource::completeRequestLVG(AppleLVMMemoryDescriptor * memoryDescriptor,
78					      IOReturn status, UInt64 actualByteCount)
79{
80    UInt32			requestIndex = memoryDescriptor->mdRequestIndex;
81    AppleRAIDStorageRequest *	storageRequest = memoryDescriptor->mdStorageRequest;
82
83    closeGate();
84
85    // Count the member as completed.
86    storageRequest->srCompletedCount++;
87
88    // Save the members results.
89    storageRequest->srRequestStatus[requestIndex] = status;
90    storageRequest->srRequestByteCounts[requestIndex] = actualByteCount;
91
92    if (storageRequest->srCompletedCount == storageRequest->srRequestCount) {
93        queue_enter(&fCompletedHead, storageRequest, AppleRAIDStorageRequest *, fCommandChain);
94
95	signalWorkAvailable();
96    }
97
98    openGate();
99}
100
101
102bool AppleRAIDEventSource::checkForWork(void)
103{
104    AppleRAIDSet	        *appleRAID = (AppleRAIDSet *)owner;
105    AppleRAIDStorageRequest 	*storageRequest;
106
107    if (!queue_empty(&fCompletedHead)) {
108	queue_remove_first(&fCompletedHead, storageRequest, AppleRAIDStorageRequest *, fCommandChain);
109
110	(*(Action)action)(appleRAID, storageRequest);
111    }
112
113    return !queue_empty(&fCompletedHead);
114}
115
116IOStorageCompletionAction AppleRAIDEventSource::getStorageCompletionAction(void)
117{
118    return OSMemberFunctionCast(IOStorageCompletionAction, this, &AppleRAIDEventSource::completeRequest);
119}
120
121IOStorageCompletionAction AppleRAIDEventSource::getStorageCompletionActionLVG(void)
122{
123    return OSMemberFunctionCast(IOStorageCompletionAction, this, &AppleRAIDEventSource::completeRequestLVG);
124}
125