|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1994 NeXT Computer, Inc.
27: *
28: * Generic Kernel Bus Interrupt Object.
29: *
30: * HISTORY
31: *
32: * 30 Jun 1994 ? at NeXT
33: * Created.
34: */
35:
36: #import <driverkit/KernBusInterrupt.h>
37: #import <driverkit/KernBusInterruptPrivate.h>
38: #import <driverkit/KernDevice.h>
39: #import <driverkit/KernLock.h>
40:
41: #import <objc/List.h>
42:
43: @implementation KernBusInterrupt
44:
45: - initForResource: resource
46: item: (unsigned int)item
47: withHandler: (void *)handler
48: shareable: (BOOL)shareable
49: {
50: [super initForResource:resource item:item shareable:shareable];
51:
52: _attachedInterrupts = [[List alloc] init];
53: _interruptLock = [[KernLock alloc] init];
54: _suspendLock = [[KernLock alloc] init];
55: #if !sparc
56: _deviceHandler = (handler != nil)? handler:
57: (shareable? KernDeviceInterruptDispatchShared:
58: KernDeviceInterruptDispatch);
59: #else
60: _deviceHandler = (handler != nil)? handler:
61: (shareable? KernDeviceInterruptDispatch:
62: KernDeviceInterruptDispatch);
63:
64: #endif
65:
66: return self;
67: }
68:
69: - initForResource: resource
70: item: (unsigned int)item
71: shareable: (BOOL)shareable
72: {
73: return [self initForResource:resource
74: item:item
75: withHandler:nil
76: shareable:shareable];
77: }
78:
79: - free
80: {
81: [_interruptLock acquire];
82:
83: if (_attachedInterruptCount > 0) {
84: [_interruptLock release];
85: return self;
86: }
87:
88: [_interruptLock release];
89:
90: return [super free];
91: }
92:
93: - dealloc
94: {
95: [_interruptLock acquire];
96:
97: if (_attachedInterruptCount > 0) {
98: [_interruptLock release];
99: return self;
100: }
101:
102: [_suspendLock acquire];
103:
104: if (++_suspendCount < 0)
105: _suspendCount--;
106:
107: [_suspendLock release];
108:
109: [_interruptLock release];
110:
111: [_attachedInterrupts free];
112:
113: [_suspendLock free];
114:
115: [_interruptLock free];
116:
117: return [super dealloc];
118: }
119:
120: - attachDeviceInterrupt: interrupt
121: {
122: id result;
123:
124: [_interruptLock acquire];
125:
126: if ([_attachedInterrupts indexOf:interrupt] == NX_NOT_IN_LIST &&
127: [_attachedInterrupts addObject:interrupt])
128: _attachedInterruptCount++;
129:
130: [_suspendLock acquire];
131:
132: result = (_attachedInterruptCount > 0) &&
133: (_suspendCount == 0)? self: nil;
134:
135: [_suspendLock release];
136:
137: [_interruptLock release];
138:
139: return result;
140: }
141:
142: - attachDeviceInterrupt: interrupt
143: atLevel: (int)level
144: {
145: return [self attachDeviceInterrupt:interrupt];
146: }
147:
148: - detachDeviceInterrupt: interrupt
149: {
150: id result;
151:
152: [_interruptLock acquire];
153:
154: if ([_attachedInterrupts removeObject:interrupt])
155: _attachedInterruptCount--;
156:
157: [_suspendLock acquire];
158:
159: result = (_attachedInterruptCount > 0) &&
160: (_suspendCount == 0)? self: nil;
161:
162: [_suspendLock release];
163:
164: [_interruptLock release];
165:
166: return result;
167: }
168:
169: - suspend
170: {
171: [_suspendLock acquire];
172:
173: if (++_suspendCount < 0)
174: _suspendCount--;
175:
176: [_suspendLock release];
177:
178: return self;
179: }
180:
181: - resume
182: {
183: id result;
184:
185: [_suspendLock acquire];
186:
187: if (_suspendCount > 0)
188: _suspendCount--;
189:
190: result = (_suspendCount == 0)? self: nil;
191:
192: [_suspendLock release];
193:
194: return result;
195: }
196:
197: @end
198:
199: BOOL
200: KernBusInterruptDispatch(
201: KernBusInterrupt *_interrupt,
202: void *state
203: )
204: {
205: KernBusInterrupt_ *interrupt = (KernBusInterrupt_ *)_interrupt;
206: KernDeviceInterrupt **deviceInterrupt;
207: int deviceInterruptCount;
208: void (*handler)() = interrupt->_deviceHandler;
209: BOOL result;
210:
211: KernLockAcquire(interrupt->_interruptLock);
212:
213: deviceInterrupt = ((List *)interrupt->_attachedInterrupts)->dataPtr;
214: deviceInterruptCount = interrupt->_attachedInterruptCount;
215:
216: while (deviceInterruptCount-- > 0)
217: (*handler)(*deviceInterrupt++, state);
218:
219: KernLockAcquire(interrupt->_suspendLock);
220:
221: result = (interrupt->_attachedInterruptCount > 0) &&
222: (interrupt->_suspendCount == 0);
223:
224: KernLockRelease(interrupt->_suspendLock);
225:
226: KernLockRelease(interrupt->_interruptLock);
227:
228: return (result);
229: }
230:
231: void
232: KernBusInterruptSuspend(
233: KernBusInterrupt *_interrupt
234: )
235: {
236: KernBusInterrupt_ *interrupt = (KernBusInterrupt_ *)_interrupt;
237:
238: if (_interrupt == nil)
239: return;
240:
241: KernLockAcquire(interrupt->_suspendLock);
242:
243: if (++interrupt->_suspendCount < 0)
244: interrupt->_suspendCount--;
245:
246: KernLockRelease(interrupt->_suspendLock);
247: }
248:
249: void
250: KernBusInterruptResume(
251: KernBusInterrupt *_interrupt
252: )
253: {
254: KernBusInterrupt_ *interrupt = (KernBusInterrupt_ *)_interrupt;
255:
256: if (_interrupt == nil)
257: return;
258:
259: KernLockAcquire(interrupt->_suspendLock);
260:
261: if (interrupt->_suspendCount > 0)
262: interrupt->_suspendCount--;
263:
264: KernLockRelease(interrupt->_suspendLock);
265: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.