2 * Copyright (c) 2007-2012 Apple Inc. All rights reserved.
3 * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
5 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. The rights granted to you under the License
11 * may not be used to create, or enable the creation or redistribution of,
12 * unlawful or unlicensed copies of an Apple operating system, or to
13 * circumvent, violate, or enable the circumvention or violation of, any
14 * terms of an Apple operating system software license agreement.
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this file.
19 * The Original Code and all software distributed under the License are
20 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
21 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
22 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
24 * Please see the License for the specific language governing rights and
25 * limitations under the License.
27 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 #include <IOKit/IOLib.h>
31 #include <IOKit/IOService.h>
32 #include <IOKit/IOPlatformExpert.h>
33 #include <IOKit/IODeviceTreeSupport.h>
34 #include <IOKit/IOInterrupts.h>
35 #include <IOKit/IOInterruptController.h>
36 #include <IOKit/IOKitDebug.h>
37 #include <IOKit/IOTimeStamp.h>
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
42 #define super IOService
44 OSDefineMetaClassAndAbstractStructors(IOInterruptController
, IOService
);
46 OSMetaClassDefineReservedUnused(IOInterruptController
, 0);
47 OSMetaClassDefineReservedUnused(IOInterruptController
, 1);
48 OSMetaClassDefineReservedUnused(IOInterruptController
, 2);
49 OSMetaClassDefineReservedUnused(IOInterruptController
, 3);
50 OSMetaClassDefineReservedUnused(IOInterruptController
, 4);
51 OSMetaClassDefineReservedUnused(IOInterruptController
, 5);
53 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
55 IOReturn
IOInterruptController::registerInterrupt(IOService
*nub
, int source
,
57 IOInterruptHandler handler
,
60 IOInterruptSource
*interruptSources
;
61 IOInterruptVectorNumber vectorNumber
;
62 IOInterruptVector
*vector
;
67 bool canBeShared
, shouldBeShared
, wasAlreadyRegisterd
;
69 IOService
*originalNub
= NULL
; // Protected by wasAlreadyRegisterd
70 int originalSource
= 0; // Protected by wasAlreadyRegisterd
73 interruptSources
= nub
->_interruptSources
;
74 vectorData
= interruptSources
[source
].vectorData
;
75 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
76 vector
= &vectors
[vectorNumber
];
78 // Get the lock for this vector.
79 IOLockLock(vector
->interruptLock
);
81 // Check if the interrupt source can/should be shared.
82 canBeShared
= vectorCanBeShared(vectorNumber
, vector
);
83 IODTGetInterruptOptions(nub
, source
, &options
);
84 #if defined(__i386__) || defined(__x86_64__)
86 if (OSDynamicCast(IOPlatformDevice
, getProvider()) &&
87 (getInterruptType(nub
, source
, &interruptType
) == kIOReturnSuccess
) &&
88 (kIOInterruptTypeLevel
& interruptType
))
90 options
|= kIODTInterruptShared
;
93 shouldBeShared
= canBeShared
&& (options
& kIODTInterruptShared
);
94 wasAlreadyRegisterd
= vector
->interruptRegistered
;
96 // If the vector is registered and can not be shared return error.
97 if (wasAlreadyRegisterd
&& !canBeShared
) {
98 IOLockUnlock(vector
->interruptLock
);
99 return kIOReturnNoResources
;
102 // If this vector is already in use, and can be shared (implied),
103 // or it is not registered and should be shared,
104 // register as a shared interrupt.
105 if (wasAlreadyRegisterd
|| shouldBeShared
) {
106 // If this vector is not already shared, break it out.
107 if (vector
->sharedController
== 0) {
108 // Make the IOShareInterruptController instance
109 vector
->sharedController
= new IOSharedInterruptController
;
110 if (vector
->sharedController
== 0) {
111 IOLockUnlock(vector
->interruptLock
);
112 return kIOReturnNoMemory
;
115 if (wasAlreadyRegisterd
) {
116 // Save the nub and source for the original consumer.
117 originalNub
= vector
->nub
;
118 originalSource
= vector
->source
;
120 // Physically disable the interrupt, but mark it as being enabled in the hardware.
121 // The interruptDisabledSoft now indicates the driver's request for enablement.
122 disableVectorHard(vectorNumber
, vector
);
123 vector
->interruptDisabledHard
= 0;
126 // Initialize the new shared interrupt controller.
127 error
= vector
->sharedController
->initInterruptController(this, vectorData
);
128 // If the IOSharedInterruptController could not be initalized,
129 // if needed, put the original consumer's interrupt back to normal and
130 // get rid of whats left of the shared controller.
131 if (error
!= kIOReturnSuccess
) {
132 if (wasAlreadyRegisterd
) enableInterrupt(originalNub
, originalSource
);
133 vector
->sharedController
->release();
134 vector
->sharedController
= 0;
135 IOLockUnlock(vector
->interruptLock
);
139 // If there was an original consumer try to register it on the shared controller.
140 if (wasAlreadyRegisterd
) {
141 error
= vector
->sharedController
->registerInterrupt(originalNub
,
146 // If the original consumer could not be moved to the shared controller,
147 // put the original consumor's interrupt back to normal and
148 // get rid of whats left of the shared controller.
149 if (error
!= kIOReturnSuccess
) {
150 // Save the driver's interrupt enablement state.
151 wasDisabledSoft
= vector
->interruptDisabledSoft
;
153 // Make the interrupt really hard disabled.
154 vector
->interruptDisabledSoft
= 1;
155 vector
->interruptDisabledHard
= 1;
157 // Enable the original consumer's interrupt if needed.
158 if (!wasDisabledSoft
) originalNub
->enableInterrupt(originalSource
);
159 enableInterrupt(originalNub
, originalSource
);
161 vector
->sharedController
->release();
162 vector
->sharedController
= 0;
163 IOLockUnlock(vector
->interruptLock
);
168 // Fill in vector with the shared controller's info.
169 vector
->handler
= (IOInterruptHandler
)vector
->sharedController
->getInterruptHandlerAddress();
170 vector
->nub
= vector
->sharedController
;
172 vector
->target
= vector
->sharedController
;
175 // If the interrupt was already registered,
176 // save the driver's interrupt enablement state.
177 if (wasAlreadyRegisterd
) wasDisabledSoft
= vector
->interruptDisabledSoft
;
178 else wasDisabledSoft
= true;
180 // Do any specific initalization for this vector if it has not yet been used.
181 if (!wasAlreadyRegisterd
) initVector(vectorNumber
, vector
);
183 // Make the interrupt really hard disabled.
184 vector
->interruptDisabledSoft
= 1;
185 vector
->interruptDisabledHard
= 1;
186 vector
->interruptRegistered
= 1;
188 // Enable the original consumer's interrupt if needed.
189 // originalNub is protected by wasAlreadyRegisterd here (see line 184).
190 if (!wasDisabledSoft
) originalNub
->enableInterrupt(originalSource
);
193 error
= vector
->sharedController
->registerInterrupt(nub
, source
, target
,
195 IOLockUnlock(vector
->interruptLock
);
199 // Fill in vector with the client's info.
200 vector
->handler
= handler
;
202 vector
->source
= source
;
203 vector
->target
= target
;
204 vector
->refCon
= refCon
;
206 // Do any specific initalization for this vector.
207 initVector(vectorNumber
, vector
);
209 // Get the vector ready. It starts hard disabled.
210 vector
->interruptDisabledHard
= 1;
211 vector
->interruptDisabledSoft
= 1;
212 vector
->interruptRegistered
= 1;
214 IOLockUnlock(vector
->interruptLock
);
215 return kIOReturnSuccess
;
218 IOReturn
IOInterruptController::unregisterInterrupt(IOService
*nub
, int source
)
220 IOInterruptSource
*interruptSources
;
221 IOInterruptVectorNumber vectorNumber
;
222 IOInterruptVector
*vector
;
225 interruptSources
= nub
->_interruptSources
;
226 vectorData
= interruptSources
[source
].vectorData
;
227 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
228 vector
= &vectors
[vectorNumber
];
230 // Get the lock for this vector.
231 IOLockLock(vector
->interruptLock
);
233 // Return success if it is not already registered
234 if (!vector
->interruptRegistered
) {
235 IOLockUnlock(vector
->interruptLock
);
236 return kIOReturnSuccess
;
239 // Soft disable the source.
240 disableInterrupt(nub
, source
);
242 // Turn the source off at hardware.
243 disableVectorHard(vectorNumber
, vector
);
245 // Clear all the storage for the vector except for interruptLock.
246 vector
->interruptActive
= 0;
247 vector
->interruptDisabledSoft
= 0;
248 vector
->interruptDisabledHard
= 0;
249 vector
->interruptRegistered
= 0;
256 IOLockUnlock(vector
->interruptLock
);
257 return kIOReturnSuccess
;
260 IOReturn
IOInterruptController::getInterruptType(IOService
*nub
, int source
,
263 IOInterruptSource
*interruptSources
;
264 IOInterruptVectorNumber vectorNumber
;
265 IOInterruptVector
*vector
;
268 if (interruptType
== 0) return kIOReturnBadArgument
;
270 interruptSources
= nub
->_interruptSources
;
271 vectorData
= interruptSources
[source
].vectorData
;
272 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
273 vector
= &vectors
[vectorNumber
];
275 *interruptType
= getVectorType(vectorNumber
, vector
);
277 return kIOReturnSuccess
;
280 IOReturn
IOInterruptController::enableInterrupt(IOService
*nub
, int source
)
282 IOInterruptSource
*interruptSources
;
283 IOInterruptVectorNumber vectorNumber
;
284 IOInterruptVector
*vector
;
287 interruptSources
= nub
->_interruptSources
;
288 vectorData
= interruptSources
[source
].vectorData
;
289 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
290 vector
= &vectors
[vectorNumber
];
292 if (vector
->interruptDisabledSoft
) {
293 vector
->interruptDisabledSoft
= 0;
294 #if !defined(__i386__) && !defined(__x86_64__)
298 if (!getPlatform()->atInterruptLevel()) {
299 while (vector
->interruptActive
)
302 if (vector
->interruptDisabledHard
) {
303 vector
->interruptDisabledHard
= 0;
305 enableVector(vectorNumber
, vector
);
309 return kIOReturnSuccess
;
312 IOReturn
IOInterruptController::disableInterrupt(IOService
*nub
, int source
)
314 IOInterruptSource
*interruptSources
;
315 IOInterruptVectorNumber vectorNumber
;
316 IOInterruptVector
*vector
;
319 interruptSources
= nub
->_interruptSources
;
320 vectorData
= interruptSources
[source
].vectorData
;
321 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
322 vector
= &vectors
[vectorNumber
];
324 vector
->interruptDisabledSoft
= 1;
325 #if !defined(__i386__) && !defined(__x86_64__)
329 if (!getPlatform()->atInterruptLevel()) {
330 while (vector
->interruptActive
)
334 return kIOReturnSuccess
;
337 IOReturn
IOInterruptController::causeInterrupt(IOService
*nub
, int source
)
339 IOInterruptSource
*interruptSources
;
340 IOInterruptVectorNumber vectorNumber
;
341 IOInterruptVector
*vector
;
344 interruptSources
= nub
->_interruptSources
;
345 vectorData
= interruptSources
[source
].vectorData
;
346 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
347 vector
= &vectors
[vectorNumber
];
349 causeVector(vectorNumber
, vector
);
351 return kIOReturnSuccess
;
354 IOInterruptAction
IOInterruptController::getInterruptHandlerAddress(void)
359 IOReturn
IOInterruptController::handleInterrupt(void *refCon
, IOService
*nub
,
362 return kIOReturnInvalid
;
366 // Methods to be overridden for simplifed interrupt controller subclasses.
368 bool IOInterruptController::vectorCanBeShared(IOInterruptVectorNumber
/*vectorNumber*/,
369 IOInterruptVector */
*vector*/
)
374 void IOInterruptController::initVector(IOInterruptVectorNumber
/*vectorNumber*/,
375 IOInterruptVector */
*vector*/
)
379 int IOInterruptController::getVectorType(IOInterruptVectorNumber
/*vectorNumber*/,
380 IOInterruptVector */
*vector*/
)
382 return kIOInterruptTypeEdge
;
385 void IOInterruptController::disableVectorHard(IOInterruptVectorNumber
/*vectorNumber*/,
386 IOInterruptVector */
*vector*/
)
390 void IOInterruptController::enableVector(IOInterruptVectorNumber
/*vectorNumber*/,
391 IOInterruptVector */
*vector*/
)
395 void IOInterruptController::causeVector(IOInterruptVectorNumber
/*vectorNumber*/,
396 IOInterruptVector */
*vector*/
)
400 void IOInterruptController::timeStampSpuriousInterrupt(void)
402 uint64_t providerID
= 0;
403 IOService
* provider
= getProvider();
406 providerID
= provider
->getRegistryEntryID();
409 IOTimeStampConstant(IODBG_INTC(IOINTC_SPURIOUS
), providerID
);
412 void IOInterruptController::timeStampInterruptHandlerInternal(bool isStart
, IOInterruptVectorNumber vectorNumber
, IOInterruptVector
*vector
)
414 uint64_t providerID
= 0;
415 vm_offset_t unslidHandler
= 0;
416 vm_offset_t unslidTarget
= 0;
418 IOService
* provider
= getProvider();
421 providerID
= provider
->getRegistryEntryID();
425 unslidHandler
= VM_KERNEL_UNSLIDE((vm_offset_t
)vector
->handler
);
426 unslidTarget
= VM_KERNEL_UNSLIDE_OR_PERM((vm_offset_t
)vector
->target
);
431 IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER
), (uintptr_t)vectorNumber
, (uintptr_t)unslidHandler
,
432 (uintptr_t)unslidTarget
, (uintptr_t)providerID
);
434 IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER
), (uintptr_t)vectorNumber
, (uintptr_t)unslidHandler
,
435 (uintptr_t)unslidTarget
, (uintptr_t)providerID
);
439 void IOInterruptController::timeStampInterruptHandlerStart(IOInterruptVectorNumber vectorNumber
, IOInterruptVector
*vector
)
441 timeStampInterruptHandlerInternal(true, vectorNumber
, vector
);
444 void IOInterruptController::timeStampInterruptHandlerEnd(IOInterruptVectorNumber vectorNumber
, IOInterruptVector
*vector
)
446 timeStampInterruptHandlerInternal(false, vectorNumber
, vector
);
449 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
452 #define super IOInterruptController
454 OSDefineMetaClassAndStructors(IOSharedInterruptController
, IOInterruptController
);
456 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 0);
457 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 1);
458 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 2);
459 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 3);
461 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
463 #define kIOSharedInterruptControllerDefaultVectors (128)
465 IOReturn
IOSharedInterruptController::initInterruptController(IOInterruptController
*parentController
, OSData
*parentSource
)
467 int cnt
, interruptType
;
473 return kIOReturnNoResources
;
475 // Set provider to this so enable/disable nub stuff works.
478 // Allocate the IOInterruptSource so this can act like a nub.
479 _interruptSources
= (IOInterruptSource
*)IOMalloc(sizeof(IOInterruptSource
));
480 if (_interruptSources
== 0) return kIOReturnNoMemory
;
481 _numInterruptSources
= 1;
483 // Set up the IOInterruptSource to point at this.
484 parentController
->retain();
485 parentSource
->retain();
486 _interruptSources
[0].interruptController
= parentController
;
487 _interruptSources
[0].vectorData
= parentSource
;
489 sourceIsLevel
= false;
490 error
= provider
->getInterruptType(0, &interruptType
);
491 if (error
== kIOReturnSuccess
) {
492 if (interruptType
& kIOInterruptTypeLevel
)
493 sourceIsLevel
= true;
496 // Allocate the memory for the vectors
497 numVectors
= kIOSharedInterruptControllerDefaultVectors
; // For now a constant number.
498 vectors
= (IOInterruptVector
*)IOMalloc(numVectors
* sizeof(IOInterruptVector
));
499 if (vectors
== NULL
) {
500 IOFree(_interruptSources
, sizeof(IOInterruptSource
));
501 return kIOReturnNoMemory
;
503 bzero(vectors
, numVectors
* sizeof(IOInterruptVector
));
505 // Allocate the lock for the controller.
506 controllerLock
= IOSimpleLockAlloc();
507 if (controllerLock
== 0) return kIOReturnNoResources
;
509 // Allocate locks for the vectors.
510 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
511 vectors
[cnt
].interruptLock
= IOLockAlloc();
512 if (vectors
[cnt
].interruptLock
== NULL
) {
513 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
514 if (vectors
[cnt
].interruptLock
!= NULL
)
515 IOLockFree(vectors
[cnt
].interruptLock
);
517 return kIOReturnNoResources
;
521 numVectors
= 0; // reset the high water mark for used vectors
522 vectorsRegistered
= 0;
524 controllerDisabled
= 1;
526 return kIOReturnSuccess
;
529 IOReturn
IOSharedInterruptController::registerInterrupt(IOService
*nub
,
532 IOInterruptHandler handler
,
535 IOInterruptSource
*interruptSources
;
536 IOInterruptVectorNumber vectorNumber
;
537 IOInterruptVector
*vector
= 0;
539 IOInterruptState interruptState
;
541 interruptSources
= nub
->_interruptSources
;
543 // Find a free vector.
544 vectorNumber
= kIOSharedInterruptControllerDefaultVectors
;
545 while (vectorsRegistered
!= kIOSharedInterruptControllerDefaultVectors
) {
546 for (vectorNumber
= 0; vectorNumber
< kIOSharedInterruptControllerDefaultVectors
; vectorNumber
++) {
547 vector
= &vectors
[vectorNumber
];
549 // Get the lock for this vector.
550 IOLockLock(vector
->interruptLock
);
552 // Is it unregistered?
553 if (!vector
->interruptRegistered
) break;
555 // Move along to the next one.
556 IOLockUnlock(vector
->interruptLock
);
559 if (vectorNumber
!= kIOSharedInterruptControllerDefaultVectors
) break;
562 // Could not find a free one, so give up.
563 if (vectorNumber
== kIOSharedInterruptControllerDefaultVectors
) {
564 return kIOReturnNoResources
;
567 // Create the vectorData for the IOInterruptSource.
568 vectorData
= OSData::withBytes(&vectorNumber
, sizeof(vectorNumber
));
569 if (vectorData
== 0) {
570 IOLockUnlock(vector
->interruptLock
);
571 return kIOReturnNoMemory
;
574 // Fill in the IOInterruptSource with the controller's info.
575 interruptSources
[source
].interruptController
= this;
576 interruptSources
[source
].vectorData
= vectorData
;
578 // Fill in vector with the client's info.
579 vector
->handler
= handler
;
581 vector
->source
= source
;
582 vector
->target
= target
;
583 vector
->refCon
= refCon
;
585 // Get the vector ready. It starts off soft disabled.
586 vector
->interruptDisabledSoft
= 1;
587 vector
->interruptRegistered
= 1;
589 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
590 // Move the high water mark if needed
591 if (++vectorsRegistered
> numVectors
) numVectors
= vectorsRegistered
;
592 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
594 IOLockUnlock(vector
->interruptLock
);
595 return kIOReturnSuccess
;
598 IOReturn
IOSharedInterruptController::unregisterInterrupt(IOService
*nub
,
601 IOInterruptVectorNumber vectorNumber
;
602 IOInterruptVector
*vector
;
603 IOInterruptState interruptState
;
605 for (vectorNumber
= 0; vectorNumber
< kIOSharedInterruptControllerDefaultVectors
; vectorNumber
++) {
606 vector
= &vectors
[vectorNumber
];
608 // Get the lock for this vector.
609 IOLockLock(vector
->interruptLock
);
611 // Return success if it is not already registered
612 if (!vector
->interruptRegistered
613 || (vector
->nub
!= nub
) || (vector
->source
!= source
)) {
614 IOLockUnlock(vector
->interruptLock
);
618 // Soft disable the source and the controller too.
619 disableInterrupt(nub
, source
);
621 // Clear all the storage for the vector except for interruptLock.
622 vector
->interruptActive
= 0;
623 vector
->interruptDisabledSoft
= 0;
624 vector
->interruptDisabledHard
= 0;
625 vector
->interruptRegistered
= 0;
632 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
634 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
636 // Move along to the next one.
637 IOLockUnlock(vector
->interruptLock
);
640 // Re-enable the controller if all vectors are enabled.
641 if (vectorsEnabled
== vectorsRegistered
) {
642 controllerDisabled
= 0;
643 provider
->enableInterrupt(0);
646 return kIOReturnSuccess
;
649 IOReturn
IOSharedInterruptController::getInterruptType(IOService */
*nub*/
,
653 return provider
->getInterruptType(0, interruptType
);
656 IOReturn
IOSharedInterruptController::enableInterrupt(IOService
*nub
,
659 IOInterruptSource
*interruptSources
;
660 IOInterruptVectorNumber vectorNumber
;
661 IOInterruptVector
*vector
;
663 IOInterruptState interruptState
;
665 interruptSources
= nub
->_interruptSources
;
666 vectorData
= interruptSources
[source
].vectorData
;
667 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
668 vector
= &vectors
[vectorNumber
];
670 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
671 if (!vector
->interruptDisabledSoft
) {
672 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
673 return kIOReturnSuccess
;
676 vector
->interruptDisabledSoft
= 0;
678 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
680 if (controllerDisabled
&& (vectorsEnabled
== vectorsRegistered
)) {
681 controllerDisabled
= 0;
682 provider
->enableInterrupt(0);
685 return kIOReturnSuccess
;
688 IOReturn
IOSharedInterruptController::disableInterrupt(IOService
*nub
,
691 IOInterruptSource
*interruptSources
;
692 IOInterruptVectorNumber vectorNumber
;
693 IOInterruptVector
*vector
;
695 IOInterruptState interruptState
;
697 interruptSources
= nub
->_interruptSources
;
698 vectorData
= interruptSources
[source
].vectorData
;
699 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
700 vector
= &vectors
[vectorNumber
];
702 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
703 if (!vector
->interruptDisabledSoft
) {
704 vector
->interruptDisabledSoft
= 1;
705 #if !defined(__i386__) && !defined(__x86_64__)
711 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
713 if (!getPlatform()->atInterruptLevel()) {
714 while (vector
->interruptActive
)
718 return kIOReturnSuccess
;
721 IOInterruptAction
IOSharedInterruptController::getInterruptHandlerAddress(void)
723 return OSMemberFunctionCast(IOInterruptAction
,
724 this, &IOSharedInterruptController::handleInterrupt
);
727 IOReturn
IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
731 IOInterruptVectorNumber vectorNumber
;
732 IOInterruptVector
*vector
;
734 for (vectorNumber
= 0; vectorNumber
< numVectors
; vectorNumber
++) {
735 vector
= &vectors
[vectorNumber
];
737 vector
->interruptActive
= 1;
738 #if !defined(__i386__) && !defined(__x86_64__)
742 if (!vector
->interruptDisabledSoft
) {
744 // Call the handler if it exists.
745 if (vector
->interruptRegistered
) {
747 bool trace
= (gIOKitTrace
& kIOTraceInterrupts
) ? true : false;
750 timeStampInterruptHandlerStart(vectorNumber
, vector
);
753 vector
->handler(vector
->target
, vector
->refCon
, vector
->nub
, vector
->source
);
756 timeStampInterruptHandlerEnd(vectorNumber
, vector
);
760 vector
->interruptActive
= 0;
763 // if any of the vectors are dissabled, then dissable this controller.
764 IOSimpleLockLock(controllerLock
);
765 if (vectorsEnabled
!= vectorsRegistered
) {
766 nub
->disableInterrupt(0);
767 controllerDisabled
= 1;
769 IOSimpleLockUnlock(controllerLock
);
771 return kIOReturnSuccess
;