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