]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOInterruptController.cpp
da1a4cef788ebdb50aa874cf84f01170dfbfec9a
[apple/xnu.git] / iokit / Kernel / IOInterruptController.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /*
31 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
32 *
33 * DRI: Josh de Cesare
34 *
35 */
36
37
38 #if __ppc__
39 #include <ppc/proc_reg.h>
40 #endif
41
42 #include <IOKit/IOLib.h>
43 #include <IOKit/IOService.h>
44 #include <IOKit/IOPlatformExpert.h>
45 #include <IOKit/IODeviceTreeSupport.h>
46 #include <IOKit/IOInterrupts.h>
47 #include <IOKit/IOInterruptController.h>
48
49
50 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
51
52 #define super IOService
53
54 OSDefineMetaClassAndAbstractStructors(IOInterruptController, IOService);
55
56 OSMetaClassDefineReservedUnused(IOInterruptController, 0);
57 OSMetaClassDefineReservedUnused(IOInterruptController, 1);
58 OSMetaClassDefineReservedUnused(IOInterruptController, 2);
59 OSMetaClassDefineReservedUnused(IOInterruptController, 3);
60 OSMetaClassDefineReservedUnused(IOInterruptController, 4);
61 OSMetaClassDefineReservedUnused(IOInterruptController, 5);
62
63 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
64
65 IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source,
66 void *target,
67 IOInterruptHandler handler,
68 void *refCon)
69 {
70 IOInterruptSource *interruptSources;
71 long vectorNumber;
72 IOInterruptVector *vector;
73 long wasDisabledSoft;
74 IOReturn error;
75 OSData *vectorData;
76 IOService *originalNub;
77 int originalSource;
78 IOOptionBits options;
79 bool canBeShared, shouldBeShared, wasAlreadyRegisterd;
80
81 interruptSources = nub->_interruptSources;
82 vectorData = interruptSources[source].vectorData;
83 vectorNumber = *(long *)vectorData->getBytesNoCopy();
84 vector = &vectors[vectorNumber];
85
86 // Get the lock for this vector.
87 IOTakeLock(vector->interruptLock);
88
89 // Check if the interrupt source can/should be shared.
90 canBeShared = vectorCanBeShared(vectorNumber, vector);
91 IODTGetInterruptOptions(nub, source, &options);
92 shouldBeShared = canBeShared && (options & kIODTInterruptShared);
93 wasAlreadyRegisterd = vector->interruptRegistered;
94
95 // If the vector is registered and can not be shared return error.
96 if (wasAlreadyRegisterd && !canBeShared) {
97 IOUnlock(vector->interruptLock);
98 return kIOReturnNoResources;
99 }
100
101 // If this vector is already in use, and can be shared (implied),
102 // or it is not registered and should be shared,
103 // register as a shared interrupt.
104 if (wasAlreadyRegisterd || shouldBeShared) {
105 // If this vector is not already shared, break it out.
106 if (vector->sharedController == 0) {
107 // Make the IOShareInterruptController instance
108 vector->sharedController = new IOSharedInterruptController;
109 if (vector->sharedController == 0) {
110 IOUnlock(vector->interruptLock);
111 return kIOReturnNoMemory;
112 }
113
114 if (wasAlreadyRegisterd) {
115 // Save the nub and source for the original consumer.
116 originalNub = vector->nub;
117 originalSource = vector->source;
118
119 // Physically disable the interrupt, but mark it as being enabled in the hardware.
120 // The interruptDisabledSoft now indicates the driver's request for enablement.
121 disableVectorHard(vectorNumber, vector);
122 vector->interruptDisabledHard = 0;
123 }
124
125 // Initialize the new shared interrupt controller.
126 error = vector->sharedController->initInterruptController(this, vectorData);
127 // If the IOSharedInterruptController could not be initalized,
128 // if needed, put the original consumer's interrupt back to normal and
129 // get rid of whats left of the shared controller.
130 if (error != kIOReturnSuccess) {
131 if (wasAlreadyRegisterd) enableInterrupt(originalNub, originalSource);
132 vector->sharedController->release();
133 vector->sharedController = 0;
134 IOUnlock(vector->interruptLock);
135 return error;
136 }
137
138 // If there was an original consumer try to register it on the shared controller.
139 if (wasAlreadyRegisterd) {
140 error = vector->sharedController->registerInterrupt(originalNub,
141 originalSource,
142 vector->target,
143 vector->handler,
144 vector->refCon);
145 // If the original consumer could not be moved to the shared controller,
146 // put the original consumor's interrupt back to normal and
147 // get rid of whats left of the shared controller.
148 if (error != kIOReturnSuccess) {
149 // Save the driver's interrupt enablement state.
150 wasDisabledSoft = vector->interruptDisabledSoft;
151
152 // Make the interrupt really hard disabled.
153 vector->interruptDisabledSoft = 1;
154 vector->interruptDisabledHard = 1;
155
156 // Enable the original consumer's interrupt if needed.
157 if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
158 enableInterrupt(originalNub, originalSource);
159
160 vector->sharedController->release();
161 vector->sharedController = 0;
162 IOUnlock(vector->interruptLock);
163 return error;
164 }
165 }
166
167 // Fill in vector with the shared controller's info.
168 vector->handler = (IOInterruptHandler)vector->sharedController->getInterruptHandlerAddress();
169 vector->nub = vector->sharedController;
170 vector->source = 0;
171 vector->target = vector->sharedController;
172 vector->refCon = 0;
173
174 // If the interrupt was already registered,
175 // save the driver's interrupt enablement state.
176 if (wasAlreadyRegisterd) wasDisabledSoft = vector->interruptDisabledSoft;
177 else wasDisabledSoft = true;
178
179 // Do any specific initalization for this vector if it has not yet been used.
180 if (!wasAlreadyRegisterd) initVector(vectorNumber, vector);
181
182 // Make the interrupt really hard disabled.
183 vector->interruptDisabledSoft = 1;
184 vector->interruptDisabledHard = 1;
185 vector->interruptRegistered = 1;
186
187 // Enable the original consumer's interrupt if needed.
188 if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
189 }
190
191 error = vector->sharedController->registerInterrupt(nub, source, target,
192 handler, refCon);
193 IOUnlock(vector->interruptLock);
194 return error;
195 }
196
197 // Fill in vector with the client's info.
198 vector->handler = handler;
199 vector->nub = nub;
200 vector->source = source;
201 vector->target = target;
202 vector->refCon = refCon;
203
204 // Do any specific initalization for this vector.
205 initVector(vectorNumber, vector);
206
207 // Get the vector ready. It starts hard disabled.
208 vector->interruptDisabledHard = 1;
209 vector->interruptDisabledSoft = 1;
210 vector->interruptRegistered = 1;
211
212 IOUnlock(vector->interruptLock);
213 return kIOReturnSuccess;
214 }
215
216 IOReturn IOInterruptController::unregisterInterrupt(IOService *nub, int source)
217 {
218 IOInterruptSource *interruptSources;
219 long vectorNumber;
220 IOInterruptVector *vector;
221 OSData *vectorData;
222
223 interruptSources = nub->_interruptSources;
224 vectorData = interruptSources[source].vectorData;
225 vectorNumber = *(long *)vectorData->getBytesNoCopy();
226 vector = &vectors[vectorNumber];
227
228 // Get the lock for this vector.
229 IOTakeLock(vector->interruptLock);
230
231 // Return success if it is not already registered
232 if (!vector->interruptRegistered) {
233 IOUnlock(vector->interruptLock);
234 return kIOReturnSuccess;
235 }
236
237 // Soft disable the source.
238 disableInterrupt(nub, source);
239
240 // Turn the source off at hardware.
241 disableVectorHard(vectorNumber, vector);
242
243 // Clear all the storage for the vector except for interruptLock.
244 vector->interruptActive = 0;
245 vector->interruptDisabledSoft = 0;
246 vector->interruptDisabledHard = 0;
247 vector->interruptRegistered = 0;
248 vector->nub = 0;
249 vector->source = 0;
250 vector->handler = 0;
251 vector->target = 0;
252 vector->refCon = 0;
253
254 IOUnlock(vector->interruptLock);
255 return kIOReturnSuccess;
256 }
257
258 IOReturn IOInterruptController::getInterruptType(IOService *nub, int source,
259 int *interruptType)
260 {
261 IOInterruptSource *interruptSources;
262 long vectorNumber;
263 IOInterruptVector *vector;
264 OSData *vectorData;
265
266 if (interruptType == 0) return kIOReturnBadArgument;
267
268 interruptSources = nub->_interruptSources;
269 vectorData = interruptSources[source].vectorData;
270 vectorNumber = *(long *)vectorData->getBytesNoCopy();
271 vector = &vectors[vectorNumber];
272
273 *interruptType = getVectorType(vectorNumber, vector);
274
275 return kIOReturnSuccess;
276 }
277
278 IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source)
279 {
280 IOInterruptSource *interruptSources;
281 long vectorNumber;
282 IOInterruptVector *vector;
283 OSData *vectorData;
284
285 interruptSources = nub->_interruptSources;
286 vectorData = interruptSources[source].vectorData;
287 vectorNumber = *(long *)vectorData->getBytesNoCopy();
288 vector = &vectors[vectorNumber];
289
290 if (vector->interruptDisabledSoft) {
291 vector->interruptDisabledSoft = 0;
292 #if __ppc__
293 sync();
294 isync();
295 #endif
296
297 if (!getPlatform()->atInterruptLevel()) {
298 while (vector->interruptActive);
299 #if __ppc__
300 isync();
301 #endif
302 }
303 if (vector->interruptDisabledHard) {
304 vector->interruptDisabledHard = 0;
305
306 enableVector(vectorNumber, vector);
307 }
308 }
309
310 return kIOReturnSuccess;
311 }
312
313 IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source)
314 {
315 IOInterruptSource *interruptSources;
316 long vectorNumber;
317 IOInterruptVector *vector;
318 OSData *vectorData;
319
320 interruptSources = nub->_interruptSources;
321 vectorData = interruptSources[source].vectorData;
322 vectorNumber = *(long *)vectorData->getBytesNoCopy();
323 vector = &vectors[vectorNumber];
324
325 vector->interruptDisabledSoft = 1;
326 #if __ppc__
327 sync();
328 isync();
329 #endif
330
331 if (!getPlatform()->atInterruptLevel()) {
332 while (vector->interruptActive);
333 #if __ppc__
334 isync();
335 #endif
336 }
337
338 return kIOReturnSuccess;
339 }
340
341 IOReturn IOInterruptController::causeInterrupt(IOService *nub, int source)
342 {
343 IOInterruptSource *interruptSources;
344 long vectorNumber;
345 IOInterruptVector *vector;
346 OSData *vectorData;
347
348 interruptSources = nub->_interruptSources;
349 vectorData = interruptSources[source].vectorData;
350 vectorNumber = *(long *)vectorData->getBytesNoCopy();
351 vector = &vectors[vectorNumber];
352
353 causeVector(vectorNumber, vector);
354
355 return kIOReturnSuccess;
356 }
357
358 IOInterruptAction IOInterruptController::getInterruptHandlerAddress(void)
359 {
360 return 0;
361 }
362
363 IOReturn IOInterruptController::handleInterrupt(void *refCon, IOService *nub,
364 int source)
365 {
366 return kIOReturnInvalid;
367 }
368
369
370 // Methods to be overridden for simplifed interrupt controller subclasses.
371
372 bool IOInterruptController::vectorCanBeShared(long /*vectorNumber*/,
373 IOInterruptVector */*vector*/)
374 {
375 return false;
376 }
377
378 void IOInterruptController::initVector(long /*vectorNumber*/,
379 IOInterruptVector */*vector*/)
380 {
381 }
382
383 int IOInterruptController::getVectorType(long /*vectorNumber*/,
384 IOInterruptVector */*vector*/)
385 {
386 return kIOInterruptTypeEdge;
387 }
388
389 void IOInterruptController::disableVectorHard(long /*vectorNumber*/,
390 IOInterruptVector */*vector*/)
391 {
392 }
393
394 void IOInterruptController::enableVector(long /*vectorNumber*/,
395 IOInterruptVector */*vector*/)
396 {
397 }
398
399 void IOInterruptController::causeVector(long /*vectorNumber*/,
400 IOInterruptVector */*vector*/)
401 {
402 }
403
404
405 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
406
407 #undef super
408 #define super IOInterruptController
409
410 OSDefineMetaClassAndStructors(IOSharedInterruptController, IOInterruptController);
411
412 OSMetaClassDefineReservedUnused(IOSharedInterruptController, 0);
413 OSMetaClassDefineReservedUnused(IOSharedInterruptController, 1);
414 OSMetaClassDefineReservedUnused(IOSharedInterruptController, 2);
415 OSMetaClassDefineReservedUnused(IOSharedInterruptController, 3);
416
417 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
418
419 #define kIOSharedInterruptControllerDefaultVectors (128)
420
421 IOReturn IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource)
422 {
423 int cnt, interruptType;
424 IOReturn error;
425
426 if (!super::init())
427 return kIOReturnNoResources;
428
429 // Set provider to this so enable/disable nub stuff works.
430 provider = this;
431
432 // Allocate the IOInterruptSource so this can act like a nub.
433 _interruptSources = (IOInterruptSource *)IOMalloc(sizeof(IOInterruptSource));
434 if (_interruptSources == 0) return kIOReturnNoMemory;
435 _numInterruptSources = 1;
436
437 // Set up the IOInterruptSource to point at this.
438 parentController->retain();
439 parentSource->retain();
440 _interruptSources[0].interruptController = parentController;
441 _interruptSources[0].vectorData = parentSource;
442
443 sourceIsLevel = false;
444 error = provider->getInterruptType(0, &interruptType);
445 if (error == kIOReturnSuccess) {
446 if (interruptType & kIOInterruptTypeLevel)
447 sourceIsLevel = true;
448 }
449
450 // Allocate the memory for the vectors
451 numVectors = kIOSharedInterruptControllerDefaultVectors; // For now a constant number.
452 vectors = (IOInterruptVector *)IOMalloc(numVectors * sizeof(IOInterruptVector));
453 if (vectors == NULL) {
454 IOFree(_interruptSources, sizeof(IOInterruptSource));
455 return kIOReturnNoMemory;
456 }
457 bzero(vectors, numVectors * sizeof(IOInterruptVector));
458
459 // Allocate the lock for the controller.
460 controllerLock = IOSimpleLockAlloc();
461 if (controllerLock == 0) return kIOReturnNoResources;
462
463 // Allocate locks for the vectors.
464 for (cnt = 0; cnt < numVectors; cnt++) {
465 vectors[cnt].interruptLock = IOLockAlloc();
466 if (vectors[cnt].interruptLock == NULL) {
467 for (cnt = 0; cnt < numVectors; cnt++) {
468 if (vectors[cnt].interruptLock != NULL)
469 IOLockFree(vectors[cnt].interruptLock);
470 }
471 return kIOReturnNoResources;
472 }
473 }
474
475 numVectors = 0; // reset the high water mark for used vectors
476 vectorsRegistered = 0;
477 vectorsEnabled = 0;
478 controllerDisabled = 1;
479
480 return kIOReturnSuccess;
481 }
482
483 IOReturn IOSharedInterruptController::registerInterrupt(IOService *nub,
484 int source,
485 void *target,
486 IOInterruptHandler handler,
487 void *refCon)
488 {
489 IOInterruptSource *interruptSources;
490 long vectorNumber;
491 IOInterruptVector *vector = 0;
492 OSData *vectorData;
493 IOInterruptState interruptState;
494
495 interruptSources = nub->_interruptSources;
496
497 // Find a free vector.
498 vectorNumber = kIOSharedInterruptControllerDefaultVectors;
499 while (vectorsRegistered != kIOSharedInterruptControllerDefaultVectors) {
500 for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
501 vector = &vectors[vectorNumber];
502
503 // Get the lock for this vector.
504 IOTakeLock(vector->interruptLock);
505
506 // Is it unregistered?
507 if (!vector->interruptRegistered) break;
508
509 // Move along to the next one.
510 IOUnlock(vector->interruptLock);
511 }
512
513 if (vectorNumber != kIOSharedInterruptControllerDefaultVectors) break;
514 }
515
516 // Could not find a free one, so give up.
517 if (vectorNumber == kIOSharedInterruptControllerDefaultVectors) {
518 return kIOReturnNoResources;
519 }
520
521 // Create the vectorData for the IOInterruptSource.
522 vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber));
523 if (vectorData == 0) {
524 return kIOReturnNoMemory;
525 }
526
527 // Fill in the IOInterruptSource with the controller's info.
528 interruptSources[source].interruptController = this;
529 interruptSources[source].vectorData = vectorData;
530
531 // Fill in vector with the client's info.
532 vector->handler = handler;
533 vector->nub = nub;
534 vector->source = source;
535 vector->target = target;
536 vector->refCon = refCon;
537
538 // Get the vector ready. It starts off soft disabled.
539 vector->interruptDisabledSoft = 1;
540 vector->interruptRegistered = 1;
541
542 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
543 // Move the high water mark if needed
544 if (++vectorsRegistered > numVectors) numVectors = vectorsRegistered;
545 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
546
547 IOUnlock(vector->interruptLock);
548 return kIOReturnSuccess;
549 }
550
551 IOReturn IOSharedInterruptController::unregisterInterrupt(IOService *nub,
552 int source)
553 {
554 IOInterruptSource *interruptSources;
555 long vectorNumber;
556 IOInterruptVector *vector;
557 OSData *vectorData;
558 IOInterruptState interruptState;
559
560 interruptSources = nub->_interruptSources;
561 vectorData = interruptSources[source].vectorData;
562 vectorNumber = *(long *)vectorData->getBytesNoCopy();
563 vector = &vectors[vectorNumber];
564
565 // Get the lock for this vector.
566 IOTakeLock(vector->interruptLock);
567
568 // Return success if it is not already registered
569 if (!vector->interruptRegistered) {
570 IOUnlock(vector->interruptLock);
571 return kIOReturnSuccess;
572 }
573
574 // Soft disable the source and the controller too.
575 disableInterrupt(nub, source);
576
577 // Clear all the storage for the vector except for interruptLock.
578 vector->interruptActive = 0;
579 vector->interruptDisabledSoft = 0;
580 vector->interruptDisabledHard = 0;
581 vector->interruptRegistered = 0;
582 vector->nub = 0;
583 vector->source = 0;
584 vector->handler = 0;
585 vector->target = 0;
586 vector->refCon = 0;
587
588 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
589 vectorsRegistered--;
590 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
591
592 IOUnlock(vector->interruptLock);
593
594 // Re-enable the controller if all vectors are enabled.
595 if (vectorsEnabled == vectorsRegistered) {
596 controllerDisabled = 0;
597 provider->enableInterrupt(0);
598 }
599
600 return kIOReturnSuccess;
601 }
602
603 IOReturn IOSharedInterruptController::getInterruptType(IOService */*nub*/,
604 int /*source*/,
605 int *interruptType)
606 {
607 return provider->getInterruptType(0, interruptType);
608 }
609
610 IOReturn IOSharedInterruptController::enableInterrupt(IOService *nub,
611 int source)
612 {
613 IOInterruptSource *interruptSources;
614 long vectorNumber;
615 IOInterruptVector *vector;
616 OSData *vectorData;
617 IOInterruptState interruptState;
618
619 interruptSources = nub->_interruptSources;
620 vectorData = interruptSources[source].vectorData;
621 vectorNumber = *(long *)vectorData->getBytesNoCopy();
622 vector = &vectors[vectorNumber];
623
624 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
625 if (!vector->interruptDisabledSoft) {
626 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
627 return kIOReturnSuccess;
628 }
629
630 vector->interruptDisabledSoft = 0;
631 vectorsEnabled++;
632 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
633
634 if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
635 controllerDisabled = 0;
636 provider->enableInterrupt(0);
637 }
638
639 return kIOReturnSuccess;
640 }
641
642 IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub,
643 int source)
644 {
645 IOInterruptSource *interruptSources;
646 long vectorNumber;
647 IOInterruptVector *vector;
648 OSData *vectorData;
649 IOInterruptState interruptState;
650
651 interruptSources = nub->_interruptSources;
652 vectorData = interruptSources[source].vectorData;
653 vectorNumber = *(long *)vectorData->getBytesNoCopy();
654 vector = &vectors[vectorNumber];
655
656 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
657 if (!vector->interruptDisabledSoft) {
658 vector->interruptDisabledSoft = 1;
659 #if __ppc__
660 sync();
661 isync();
662 #endif
663 vectorsEnabled--;
664 }
665 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
666
667 if (!getPlatform()->atInterruptLevel()) {
668 while (vector->interruptActive);
669 #if __ppc__
670 isync();
671 #endif
672 }
673
674 return kIOReturnSuccess;
675 }
676
677 IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void)
678 {
679 return OSMemberFunctionCast(IOInterruptAction,
680 this, &IOSharedInterruptController::handleInterrupt);
681 }
682
683 IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
684 IOService * nub,
685 int /*source*/)
686 {
687 long vectorNumber;
688 IOInterruptVector *vector;
689
690 for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
691 vector = &vectors[vectorNumber];
692
693 vector->interruptActive = 1;
694 #if __ppc__
695 sync();
696 isync();
697 #endif
698 if (!vector->interruptDisabledSoft) {
699 #if __ppc__
700 isync();
701 #endif
702
703 // Call the handler if it exists.
704 if (vector->interruptRegistered) {
705 vector->handler(vector->target, vector->refCon,
706 vector->nub, vector->source);
707 }
708 }
709
710 vector->interruptActive = 0;
711 }
712
713 // if any of the vectors are dissabled, then dissable this controller.
714 IOSimpleLockLock(controllerLock);
715 if (vectorsEnabled != vectorsRegistered) {
716 nub->disableInterrupt(0);
717 controllerDisabled = 1;
718 }
719 IOSimpleLockUnlock(controllerLock);
720
721 return kIOReturnSuccess;
722 }
723