2 * Copyright (c) 1998-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 #include <ppc/proc_reg.h>
34 #include <IOKit/IOLib.h>
35 #include <IOKit/IOService.h>
36 #include <IOKit/IOPlatformExpert.h>
37 #include <IOKit/IODeviceTreeSupport.h>
38 #include <IOKit/IOInterrupts.h>
39 #include <IOKit/IOInterruptController.h>
40 #include <IOKit/IOKitDebug.h>
41 #include <IOKit/IOTimeStamp.h>
44 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46 #define super IOService
48 OSDefineMetaClassAndAbstractStructors(IOInterruptController
, IOService
);
50 OSMetaClassDefineReservedUnused(IOInterruptController
, 0);
51 OSMetaClassDefineReservedUnused(IOInterruptController
, 1);
52 OSMetaClassDefineReservedUnused(IOInterruptController
, 2);
53 OSMetaClassDefineReservedUnused(IOInterruptController
, 3);
54 OSMetaClassDefineReservedUnused(IOInterruptController
, 4);
55 OSMetaClassDefineReservedUnused(IOInterruptController
, 5);
57 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
59 IOReturn
IOInterruptController::registerInterrupt(IOService
*nub
, int source
,
61 IOInterruptHandler handler
,
64 IOInterruptSource
*interruptSources
;
65 IOInterruptVectorNumber vectorNumber
;
66 IOInterruptVector
*vector
;
71 bool canBeShared
, shouldBeShared
, wasAlreadyRegisterd
;
73 IOService
*originalNub
= NULL
; // Protected by wasAlreadyRegisterd
74 int originalSource
= 0; // Protected by wasAlreadyRegisterd
77 interruptSources
= nub
->_interruptSources
;
78 vectorData
= interruptSources
[source
].vectorData
;
79 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
80 vector
= &vectors
[vectorNumber
];
82 // Get the lock for this vector.
83 IOLockLock(vector
->interruptLock
);
85 // Check if the interrupt source can/should be shared.
86 canBeShared
= vectorCanBeShared(vectorNumber
, vector
);
87 IODTGetInterruptOptions(nub
, source
, &options
);
88 #if defined(__i386__) || defined(__x86_64__)
90 if (OSDynamicCast(IOPlatformDevice
, getProvider()) &&
91 (getInterruptType(nub
, source
, &interruptType
) == kIOReturnSuccess
) &&
92 (kIOInterruptTypeLevel
& interruptType
))
94 options
|= kIODTInterruptShared
;
97 shouldBeShared
= canBeShared
&& (options
& kIODTInterruptShared
);
98 wasAlreadyRegisterd
= vector
->interruptRegistered
;
100 // If the vector is registered and can not be shared return error.
101 if (wasAlreadyRegisterd
&& !canBeShared
) {
102 IOLockUnlock(vector
->interruptLock
);
103 return kIOReturnNoResources
;
106 // If this vector is already in use, and can be shared (implied),
107 // or it is not registered and should be shared,
108 // register as a shared interrupt.
109 if (wasAlreadyRegisterd
|| shouldBeShared
) {
110 // If this vector is not already shared, break it out.
111 if (vector
->sharedController
== 0) {
112 // Make the IOShareInterruptController instance
113 vector
->sharedController
= new IOSharedInterruptController
;
114 if (vector
->sharedController
== 0) {
115 IOLockUnlock(vector
->interruptLock
);
116 return kIOReturnNoMemory
;
119 if (wasAlreadyRegisterd
) {
120 // Save the nub and source for the original consumer.
121 originalNub
= vector
->nub
;
122 originalSource
= vector
->source
;
124 // Physically disable the interrupt, but mark it as being enabled in the hardware.
125 // The interruptDisabledSoft now indicates the driver's request for enablement.
126 disableVectorHard(vectorNumber
, vector
);
127 vector
->interruptDisabledHard
= 0;
130 // Initialize the new shared interrupt controller.
131 error
= vector
->sharedController
->initInterruptController(this, vectorData
);
132 // If the IOSharedInterruptController could not be initalized,
133 // if needed, put the original consumer's interrupt back to normal and
134 // get rid of whats left of the shared controller.
135 if (error
!= kIOReturnSuccess
) {
136 if (wasAlreadyRegisterd
) enableInterrupt(originalNub
, originalSource
);
137 vector
->sharedController
->release();
138 vector
->sharedController
= 0;
139 IOLockUnlock(vector
->interruptLock
);
143 // If there was an original consumer try to register it on the shared controller.
144 if (wasAlreadyRegisterd
) {
145 error
= vector
->sharedController
->registerInterrupt(originalNub
,
150 // If the original consumer could not be moved to the shared controller,
151 // put the original consumor's interrupt back to normal and
152 // get rid of whats left of the shared controller.
153 if (error
!= kIOReturnSuccess
) {
154 // Save the driver's interrupt enablement state.
155 wasDisabledSoft
= vector
->interruptDisabledSoft
;
157 // Make the interrupt really hard disabled.
158 vector
->interruptDisabledSoft
= 1;
159 vector
->interruptDisabledHard
= 1;
161 // Enable the original consumer's interrupt if needed.
162 if (!wasDisabledSoft
) originalNub
->enableInterrupt(originalSource
);
163 enableInterrupt(originalNub
, originalSource
);
165 vector
->sharedController
->release();
166 vector
->sharedController
= 0;
167 IOLockUnlock(vector
->interruptLock
);
172 // Fill in vector with the shared controller's info.
173 vector
->handler
= (IOInterruptHandler
)vector
->sharedController
->getInterruptHandlerAddress();
174 vector
->nub
= vector
->sharedController
;
176 vector
->target
= vector
->sharedController
;
179 // If the interrupt was already registered,
180 // save the driver's interrupt enablement state.
181 if (wasAlreadyRegisterd
) wasDisabledSoft
= vector
->interruptDisabledSoft
;
182 else wasDisabledSoft
= true;
184 // Do any specific initalization for this vector if it has not yet been used.
185 if (!wasAlreadyRegisterd
) initVector(vectorNumber
, vector
);
187 // Make the interrupt really hard disabled.
188 vector
->interruptDisabledSoft
= 1;
189 vector
->interruptDisabledHard
= 1;
190 vector
->interruptRegistered
= 1;
192 // Enable the original consumer's interrupt if needed.
193 // originalNub is protected by wasAlreadyRegisterd here (see line 184).
194 if (!wasDisabledSoft
) originalNub
->enableInterrupt(originalSource
);
197 error
= vector
->sharedController
->registerInterrupt(nub
, source
, target
,
199 IOLockUnlock(vector
->interruptLock
);
203 // Fill in vector with the client's info.
204 vector
->handler
= handler
;
206 vector
->source
= source
;
207 vector
->target
= target
;
208 vector
->refCon
= refCon
;
210 // Do any specific initalization for this vector.
211 initVector(vectorNumber
, vector
);
213 // Get the vector ready. It starts hard disabled.
214 vector
->interruptDisabledHard
= 1;
215 vector
->interruptDisabledSoft
= 1;
216 vector
->interruptRegistered
= 1;
218 IOLockUnlock(vector
->interruptLock
);
219 return kIOReturnSuccess
;
222 IOReturn
IOInterruptController::unregisterInterrupt(IOService
*nub
, int source
)
224 IOInterruptSource
*interruptSources
;
225 IOInterruptVectorNumber vectorNumber
;
226 IOInterruptVector
*vector
;
229 interruptSources
= nub
->_interruptSources
;
230 vectorData
= interruptSources
[source
].vectorData
;
231 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
232 vector
= &vectors
[vectorNumber
];
234 // Get the lock for this vector.
235 IOLockLock(vector
->interruptLock
);
237 // Return success if it is not already registered
238 if (!vector
->interruptRegistered
) {
239 IOLockUnlock(vector
->interruptLock
);
240 return kIOReturnSuccess
;
243 // Soft disable the source.
244 disableInterrupt(nub
, source
);
246 // Turn the source off at hardware.
247 disableVectorHard(vectorNumber
, vector
);
249 // Clear all the storage for the vector except for interruptLock.
250 vector
->interruptActive
= 0;
251 vector
->interruptDisabledSoft
= 0;
252 vector
->interruptDisabledHard
= 0;
253 vector
->interruptRegistered
= 0;
260 IOLockUnlock(vector
->interruptLock
);
261 return kIOReturnSuccess
;
264 IOReturn
IOInterruptController::getInterruptType(IOService
*nub
, int source
,
267 IOInterruptSource
*interruptSources
;
268 IOInterruptVectorNumber vectorNumber
;
269 IOInterruptVector
*vector
;
272 if (interruptType
== 0) return kIOReturnBadArgument
;
274 interruptSources
= nub
->_interruptSources
;
275 vectorData
= interruptSources
[source
].vectorData
;
276 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
277 vector
= &vectors
[vectorNumber
];
279 *interruptType
= getVectorType(vectorNumber
, vector
);
281 return kIOReturnSuccess
;
284 IOReturn
IOInterruptController::enableInterrupt(IOService
*nub
, int source
)
286 IOInterruptSource
*interruptSources
;
287 IOInterruptVectorNumber vectorNumber
;
288 IOInterruptVector
*vector
;
291 interruptSources
= nub
->_interruptSources
;
292 vectorData
= interruptSources
[source
].vectorData
;
293 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
294 vector
= &vectors
[vectorNumber
];
296 if (vector
->interruptDisabledSoft
) {
297 vector
->interruptDisabledSoft
= 0;
303 if (!getPlatform()->atInterruptLevel()) {
304 while (vector
->interruptActive
)
310 if (vector
->interruptDisabledHard
) {
311 vector
->interruptDisabledHard
= 0;
313 enableVector(vectorNumber
, vector
);
317 return kIOReturnSuccess
;
320 IOReturn
IOInterruptController::disableInterrupt(IOService
*nub
, int source
)
322 IOInterruptSource
*interruptSources
;
323 IOInterruptVectorNumber vectorNumber
;
324 IOInterruptVector
*vector
;
327 interruptSources
= nub
->_interruptSources
;
328 vectorData
= interruptSources
[source
].vectorData
;
329 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
330 vector
= &vectors
[vectorNumber
];
332 vector
->interruptDisabledSoft
= 1;
338 if (!getPlatform()->atInterruptLevel()) {
339 while (vector
->interruptActive
)
346 return kIOReturnSuccess
;
349 IOReturn
IOInterruptController::causeInterrupt(IOService
*nub
, int source
)
351 IOInterruptSource
*interruptSources
;
352 IOInterruptVectorNumber vectorNumber
;
353 IOInterruptVector
*vector
;
356 interruptSources
= nub
->_interruptSources
;
357 vectorData
= interruptSources
[source
].vectorData
;
358 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
359 vector
= &vectors
[vectorNumber
];
361 causeVector(vectorNumber
, vector
);
363 return kIOReturnSuccess
;
366 IOInterruptAction
IOInterruptController::getInterruptHandlerAddress(void)
371 IOReturn
IOInterruptController::handleInterrupt(void *refCon
, IOService
*nub
,
374 return kIOReturnInvalid
;
378 // Methods to be overridden for simplifed interrupt controller subclasses.
380 bool IOInterruptController::vectorCanBeShared(IOInterruptVectorNumber
/*vectorNumber*/,
381 IOInterruptVector */
*vector*/
)
386 void IOInterruptController::initVector(IOInterruptVectorNumber
/*vectorNumber*/,
387 IOInterruptVector */
*vector*/
)
391 int IOInterruptController::getVectorType(IOInterruptVectorNumber
/*vectorNumber*/,
392 IOInterruptVector */
*vector*/
)
394 return kIOInterruptTypeEdge
;
397 void IOInterruptController::disableVectorHard(IOInterruptVectorNumber
/*vectorNumber*/,
398 IOInterruptVector */
*vector*/
)
402 void IOInterruptController::enableVector(IOInterruptVectorNumber
/*vectorNumber*/,
403 IOInterruptVector */
*vector*/
)
407 void IOInterruptController::causeVector(IOInterruptVectorNumber
/*vectorNumber*/,
408 IOInterruptVector */
*vector*/
)
413 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
416 #define super IOInterruptController
418 OSDefineMetaClassAndStructors(IOSharedInterruptController
, IOInterruptController
);
420 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 0);
421 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 1);
422 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 2);
423 OSMetaClassDefineReservedUnused(IOSharedInterruptController
, 3);
425 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
427 #define kIOSharedInterruptControllerDefaultVectors (128)
429 IOReturn
IOSharedInterruptController::initInterruptController(IOInterruptController
*parentController
, OSData
*parentSource
)
431 int cnt
, interruptType
;
435 return kIOReturnNoResources
;
437 // Set provider to this so enable/disable nub stuff works.
440 // Allocate the IOInterruptSource so this can act like a nub.
441 _interruptSources
= (IOInterruptSource
*)IOMalloc(sizeof(IOInterruptSource
));
442 if (_interruptSources
== 0) return kIOReturnNoMemory
;
443 _numInterruptSources
= 1;
445 // Set up the IOInterruptSource to point at this.
446 parentController
->retain();
447 parentSource
->retain();
448 _interruptSources
[0].interruptController
= parentController
;
449 _interruptSources
[0].vectorData
= parentSource
;
451 sourceIsLevel
= false;
452 error
= provider
->getInterruptType(0, &interruptType
);
453 if (error
== kIOReturnSuccess
) {
454 if (interruptType
& kIOInterruptTypeLevel
)
455 sourceIsLevel
= true;
458 // Allocate the memory for the vectors
459 numVectors
= kIOSharedInterruptControllerDefaultVectors
; // For now a constant number.
460 vectors
= (IOInterruptVector
*)IOMalloc(numVectors
* sizeof(IOInterruptVector
));
461 if (vectors
== NULL
) {
462 IOFree(_interruptSources
, sizeof(IOInterruptSource
));
463 return kIOReturnNoMemory
;
465 bzero(vectors
, numVectors
* sizeof(IOInterruptVector
));
467 // Allocate the lock for the controller.
468 controllerLock
= IOSimpleLockAlloc();
469 if (controllerLock
== 0) return kIOReturnNoResources
;
471 // Allocate locks for the vectors.
472 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
473 vectors
[cnt
].interruptLock
= IOLockAlloc();
474 if (vectors
[cnt
].interruptLock
== NULL
) {
475 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
476 if (vectors
[cnt
].interruptLock
!= NULL
)
477 IOLockFree(vectors
[cnt
].interruptLock
);
479 return kIOReturnNoResources
;
483 numVectors
= 0; // reset the high water mark for used vectors
484 vectorsRegistered
= 0;
486 controllerDisabled
= 1;
488 return kIOReturnSuccess
;
491 IOReturn
IOSharedInterruptController::registerInterrupt(IOService
*nub
,
494 IOInterruptHandler handler
,
497 IOInterruptSource
*interruptSources
;
498 IOInterruptVectorNumber vectorNumber
;
499 IOInterruptVector
*vector
= 0;
501 IOInterruptState interruptState
;
503 interruptSources
= nub
->_interruptSources
;
505 // Find a free vector.
506 vectorNumber
= kIOSharedInterruptControllerDefaultVectors
;
507 while (vectorsRegistered
!= kIOSharedInterruptControllerDefaultVectors
) {
508 for (vectorNumber
= 0; vectorNumber
< kIOSharedInterruptControllerDefaultVectors
; vectorNumber
++) {
509 vector
= &vectors
[vectorNumber
];
511 // Get the lock for this vector.
512 IOLockLock(vector
->interruptLock
);
514 // Is it unregistered?
515 if (!vector
->interruptRegistered
) break;
517 // Move along to the next one.
518 IOLockUnlock(vector
->interruptLock
);
521 if (vectorNumber
!= kIOSharedInterruptControllerDefaultVectors
) break;
524 // Could not find a free one, so give up.
525 if (vectorNumber
== kIOSharedInterruptControllerDefaultVectors
) {
526 return kIOReturnNoResources
;
529 // Create the vectorData for the IOInterruptSource.
530 vectorData
= OSData::withBytes(&vectorNumber
, sizeof(vectorNumber
));
531 if (vectorData
== 0) {
532 return kIOReturnNoMemory
;
535 // Fill in the IOInterruptSource with the controller's info.
536 interruptSources
[source
].interruptController
= this;
537 interruptSources
[source
].vectorData
= vectorData
;
539 // Fill in vector with the client's info.
540 vector
->handler
= handler
;
542 vector
->source
= source
;
543 vector
->target
= target
;
544 vector
->refCon
= refCon
;
546 // Get the vector ready. It starts off soft disabled.
547 vector
->interruptDisabledSoft
= 1;
548 vector
->interruptRegistered
= 1;
550 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
551 // Move the high water mark if needed
552 if (++vectorsRegistered
> numVectors
) numVectors
= vectorsRegistered
;
553 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
555 IOLockUnlock(vector
->interruptLock
);
556 return kIOReturnSuccess
;
559 IOReturn
IOSharedInterruptController::unregisterInterrupt(IOService
*nub
,
562 IOInterruptVectorNumber vectorNumber
;
563 IOInterruptVector
*vector
;
564 IOInterruptState interruptState
;
566 for (vectorNumber
= 0; vectorNumber
< kIOSharedInterruptControllerDefaultVectors
; vectorNumber
++) {
567 vector
= &vectors
[vectorNumber
];
569 // Get the lock for this vector.
570 IOLockLock(vector
->interruptLock
);
572 // Return success if it is not already registered
573 if (!vector
->interruptRegistered
574 || (vector
->nub
!= nub
) || (vector
->source
!= source
)) {
575 IOLockUnlock(vector
->interruptLock
);
579 // Soft disable the source and the controller too.
580 disableInterrupt(nub
, source
);
582 // Clear all the storage for the vector except for interruptLock.
583 vector
->interruptActive
= 0;
584 vector
->interruptDisabledSoft
= 0;
585 vector
->interruptDisabledHard
= 0;
586 vector
->interruptRegistered
= 0;
593 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
595 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
597 // Move along to the next one.
598 IOLockUnlock(vector
->interruptLock
);
601 // Re-enable the controller if all vectors are enabled.
602 if (vectorsEnabled
== vectorsRegistered
) {
603 controllerDisabled
= 0;
604 provider
->enableInterrupt(0);
607 return kIOReturnSuccess
;
610 IOReturn
IOSharedInterruptController::getInterruptType(IOService */
*nub*/
,
614 return provider
->getInterruptType(0, interruptType
);
617 IOReturn
IOSharedInterruptController::enableInterrupt(IOService
*nub
,
620 IOInterruptSource
*interruptSources
;
621 IOInterruptVectorNumber vectorNumber
;
622 IOInterruptVector
*vector
;
624 IOInterruptState interruptState
;
626 interruptSources
= nub
->_interruptSources
;
627 vectorData
= interruptSources
[source
].vectorData
;
628 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
629 vector
= &vectors
[vectorNumber
];
631 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
632 if (!vector
->interruptDisabledSoft
) {
633 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
634 return kIOReturnSuccess
;
637 vector
->interruptDisabledSoft
= 0;
639 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
641 if (controllerDisabled
&& (vectorsEnabled
== vectorsRegistered
)) {
642 controllerDisabled
= 0;
643 provider
->enableInterrupt(0);
646 return kIOReturnSuccess
;
649 IOReturn
IOSharedInterruptController::disableInterrupt(IOService
*nub
,
652 IOInterruptSource
*interruptSources
;
653 IOInterruptVectorNumber vectorNumber
;
654 IOInterruptVector
*vector
;
656 IOInterruptState interruptState
;
658 interruptSources
= nub
->_interruptSources
;
659 vectorData
= interruptSources
[source
].vectorData
;
660 vectorNumber
= *(IOInterruptVectorNumber
*)vectorData
->getBytesNoCopy();
661 vector
= &vectors
[vectorNumber
];
663 interruptState
= IOSimpleLockLockDisableInterrupt(controllerLock
);
664 if (!vector
->interruptDisabledSoft
) {
665 vector
->interruptDisabledSoft
= 1;
672 IOSimpleLockUnlockEnableInterrupt(controllerLock
, interruptState
);
674 if (!getPlatform()->atInterruptLevel()) {
675 while (vector
->interruptActive
)
682 return kIOReturnSuccess
;
685 IOInterruptAction
IOSharedInterruptController::getInterruptHandlerAddress(void)
687 return OSMemberFunctionCast(IOInterruptAction
,
688 this, &IOSharedInterruptController::handleInterrupt
);
691 IOReturn
IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
695 IOInterruptVectorNumber vectorNumber
;
696 IOInterruptVector
*vector
;
698 for (vectorNumber
= 0; vectorNumber
< numVectors
; vectorNumber
++) {
699 vector
= &vectors
[vectorNumber
];
701 vector
->interruptActive
= 1;
706 if (!vector
->interruptDisabledSoft
) {
711 // Call the handler if it exists.
712 if (vector
->interruptRegistered
) {
714 bool trace
= (gIOKitTrace
& kIOTraceInterrupts
) ? true : false;
715 bool timeHandler
= gIOInterruptThresholdNS
? true : false;
716 uint64_t startTime
= 0;
717 uint64_t endTime
= 0;
720 IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER
),
721 (uintptr_t) vectorNumber
, (uintptr_t) vector
->handler
, (uintptr_t)vector
->target
);
724 startTime
= mach_absolute_time();
727 vector
->handler(vector
->target
, vector
->refCon
, vector
->nub
, vector
->source
);
731 endTime
= mach_absolute_time();
732 if ((endTime
- startTime
) > gIOInterruptThresholdNS
)
733 panic("IOSIC::handleInterrupt: interrupt exceeded threshold, handlerTime = %qd, vectorNumber = %d, handler = %p, target = %p\n",
734 endTime
- startTime
, (int)vectorNumber
, vector
->handler
, vector
->target
);
738 IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER
),
739 (uintptr_t) vectorNumber
, (uintptr_t) vector
->handler
, (uintptr_t)vector
->target
);
745 vector
->interruptActive
= 0;
748 // if any of the vectors are dissabled, then dissable this controller.
749 IOSimpleLockLock(controllerLock
);
750 if (vectorsEnabled
!= vectorsRegistered
) {
751 nub
->disableInterrupt(0);
752 controllerDisabled
= 1;
754 IOSimpleLockUnlock(controllerLock
);
756 return kIOReturnSuccess
;