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