1/* 2 * Copyright (c) 1998-2010 Apple 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#include <IOKit/IOLib.h> 30#include <IOKit/IOService.h> 31#include <IOKit/IOPlatformExpert.h> 32#include <IOKit/IODeviceTreeSupport.h> 33#include <IOKit/IOInterrupts.h> 34#include <IOKit/IOInterruptController.h> 35#include <IOKit/IOKitDebug.h> 36#include <IOKit/IOTimeStamp.h> 37 38 39/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 40 41#define super IOService 42 43OSDefineMetaClassAndAbstractStructors(IOInterruptController, IOService); 44 45OSMetaClassDefineReservedUnused(IOInterruptController, 0); 46OSMetaClassDefineReservedUnused(IOInterruptController, 1); 47OSMetaClassDefineReservedUnused(IOInterruptController, 2); 48OSMetaClassDefineReservedUnused(IOInterruptController, 3); 49OSMetaClassDefineReservedUnused(IOInterruptController, 4); 50OSMetaClassDefineReservedUnused(IOInterruptController, 5); 51 52/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 53 54IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source, 55 void *target, 56 IOInterruptHandler handler, 57 void *refCon) 58{ 59 IOInterruptSource *interruptSources; 60 IOInterruptVectorNumber vectorNumber; 61 IOInterruptVector *vector; 62 int wasDisabledSoft; 63 IOReturn error; 64 OSData *vectorData; 65 IOOptionBits options; 66 bool canBeShared, shouldBeShared, wasAlreadyRegisterd; 67 68 IOService *originalNub = NULL; // Protected by wasAlreadyRegisterd 69 int originalSource = 0; // Protected by wasAlreadyRegisterd 70 71 72 interruptSources = nub->_interruptSources; 73 vectorData = interruptSources[source].vectorData; 74 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 75 vector = &vectors[vectorNumber]; 76 77 // Get the lock for this vector. 78 IOLockLock(vector->interruptLock); 79 80 // Check if the interrupt source can/should be shared. 81 canBeShared = vectorCanBeShared(vectorNumber, vector); 82 IODTGetInterruptOptions(nub, source, &options); 83#if defined(__i386__) || defined(__x86_64__) 84 int interruptType; 85 if (OSDynamicCast(IOPlatformDevice, getProvider()) && 86 (getInterruptType(nub, source, &interruptType) == kIOReturnSuccess) && 87 (kIOInterruptTypeLevel & interruptType)) 88 { 89 options |= kIODTInterruptShared; 90 } 91#endif 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 IOLockUnlock(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 IOLockUnlock(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 IOLockUnlock(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 IOLockUnlock(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 // originalNub is protected by wasAlreadyRegisterd here (see line 184). 189 if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource); 190 } 191 192 error = vector->sharedController->registerInterrupt(nub, source, target, 193 handler, refCon); 194 IOLockUnlock(vector->interruptLock); 195 return error; 196 } 197 198 // Fill in vector with the client's info. 199 vector->handler = handler; 200 vector->nub = nub; 201 vector->source = source; 202 vector->target = target; 203 vector->refCon = refCon; 204 205 // Do any specific initalization for this vector. 206 initVector(vectorNumber, vector); 207 208 // Get the vector ready. It starts hard disabled. 209 vector->interruptDisabledHard = 1; 210 vector->interruptDisabledSoft = 1; 211 vector->interruptRegistered = 1; 212 213 IOLockUnlock(vector->interruptLock); 214 return kIOReturnSuccess; 215} 216 217IOReturn IOInterruptController::unregisterInterrupt(IOService *nub, int source) 218{ 219 IOInterruptSource *interruptSources; 220 IOInterruptVectorNumber vectorNumber; 221 IOInterruptVector *vector; 222 OSData *vectorData; 223 224 interruptSources = nub->_interruptSources; 225 vectorData = interruptSources[source].vectorData; 226 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 227 vector = &vectors[vectorNumber]; 228 229 // Get the lock for this vector. 230 IOLockLock(vector->interruptLock); 231 232 // Return success if it is not already registered 233 if (!vector->interruptRegistered) { 234 IOLockUnlock(vector->interruptLock); 235 return kIOReturnSuccess; 236 } 237 238 // Soft disable the source. 239 disableInterrupt(nub, source); 240 241 // Turn the source off at hardware. 242 disableVectorHard(vectorNumber, vector); 243 244 // Clear all the storage for the vector except for interruptLock. 245 vector->interruptActive = 0; 246 vector->interruptDisabledSoft = 0; 247 vector->interruptDisabledHard = 0; 248 vector->interruptRegistered = 0; 249 vector->nub = 0; 250 vector->source = 0; 251 vector->handler = 0; 252 vector->target = 0; 253 vector->refCon = 0; 254 255 IOLockUnlock(vector->interruptLock); 256 return kIOReturnSuccess; 257} 258 259IOReturn IOInterruptController::getInterruptType(IOService *nub, int source, 260 int *interruptType) 261{ 262 IOInterruptSource *interruptSources; 263 IOInterruptVectorNumber vectorNumber; 264 IOInterruptVector *vector; 265 OSData *vectorData; 266 267 if (interruptType == 0) return kIOReturnBadArgument; 268 269 interruptSources = nub->_interruptSources; 270 vectorData = interruptSources[source].vectorData; 271 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 272 vector = &vectors[vectorNumber]; 273 274 *interruptType = getVectorType(vectorNumber, vector); 275 276 return kIOReturnSuccess; 277} 278 279IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source) 280{ 281 IOInterruptSource *interruptSources; 282 IOInterruptVectorNumber vectorNumber; 283 IOInterruptVector *vector; 284 OSData *vectorData; 285 286 interruptSources = nub->_interruptSources; 287 vectorData = interruptSources[source].vectorData; 288 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 289 vector = &vectors[vectorNumber]; 290 291 if (vector->interruptDisabledSoft) { 292 vector->interruptDisabledSoft = 0; 293 294 if (!getPlatform()->atInterruptLevel()) { 295 while (vector->interruptActive) 296 {} 297 } 298 if (vector->interruptDisabledHard) { 299 vector->interruptDisabledHard = 0; 300 301 enableVector(vectorNumber, vector); 302 } 303 } 304 305 return kIOReturnSuccess; 306} 307 308IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source) 309{ 310 IOInterruptSource *interruptSources; 311 IOInterruptVectorNumber vectorNumber; 312 IOInterruptVector *vector; 313 OSData *vectorData; 314 315 interruptSources = nub->_interruptSources; 316 vectorData = interruptSources[source].vectorData; 317 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 318 vector = &vectors[vectorNumber]; 319 320 vector->interruptDisabledSoft = 1; 321 322 if (!getPlatform()->atInterruptLevel()) { 323 while (vector->interruptActive) 324 {} 325 } 326 327 return kIOReturnSuccess; 328} 329 330IOReturn IOInterruptController::causeInterrupt(IOService *nub, int source) 331{ 332 IOInterruptSource *interruptSources; 333 IOInterruptVectorNumber vectorNumber; 334 IOInterruptVector *vector; 335 OSData *vectorData; 336 337 interruptSources = nub->_interruptSources; 338 vectorData = interruptSources[source].vectorData; 339 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 340 vector = &vectors[vectorNumber]; 341 342 causeVector(vectorNumber, vector); 343 344 return kIOReturnSuccess; 345} 346 347IOInterruptAction IOInterruptController::getInterruptHandlerAddress(void) 348{ 349 return 0; 350} 351 352IOReturn IOInterruptController::handleInterrupt(void *refCon, IOService *nub, 353 int source) 354{ 355 return kIOReturnInvalid; 356} 357 358 359// Methods to be overridden for simplifed interrupt controller subclasses. 360 361bool IOInterruptController::vectorCanBeShared(IOInterruptVectorNumber /*vectorNumber*/, 362 IOInterruptVector */*vector*/) 363{ 364 return false; 365} 366 367void IOInterruptController::initVector(IOInterruptVectorNumber /*vectorNumber*/, 368 IOInterruptVector */*vector*/) 369{ 370} 371 372int IOInterruptController::getVectorType(IOInterruptVectorNumber /*vectorNumber*/, 373 IOInterruptVector */*vector*/) 374{ 375 return kIOInterruptTypeEdge; 376} 377 378void IOInterruptController::disableVectorHard(IOInterruptVectorNumber /*vectorNumber*/, 379 IOInterruptVector */*vector*/) 380{ 381} 382 383void IOInterruptController::enableVector(IOInterruptVectorNumber /*vectorNumber*/, 384 IOInterruptVector */*vector*/) 385{ 386} 387 388void IOInterruptController::causeVector(IOInterruptVectorNumber /*vectorNumber*/, 389 IOInterruptVector */*vector*/) 390{ 391} 392 393 394/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 395 396#undef super 397#define super IOInterruptController 398 399OSDefineMetaClassAndStructors(IOSharedInterruptController, IOInterruptController); 400 401OSMetaClassDefineReservedUnused(IOSharedInterruptController, 0); 402OSMetaClassDefineReservedUnused(IOSharedInterruptController, 1); 403OSMetaClassDefineReservedUnused(IOSharedInterruptController, 2); 404OSMetaClassDefineReservedUnused(IOSharedInterruptController, 3); 405 406/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 407 408#define kIOSharedInterruptControllerDefaultVectors (128) 409 410IOReturn IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource) 411{ 412 int cnt, interruptType; 413 IOReturn error; 414 415 if (!super::init()) 416 return kIOReturnNoResources; 417 418 // Set provider to this so enable/disable nub stuff works. 419 provider = this; 420 421 // Allocate the IOInterruptSource so this can act like a nub. 422 _interruptSources = (IOInterruptSource *)IOMalloc(sizeof(IOInterruptSource)); 423 if (_interruptSources == 0) return kIOReturnNoMemory; 424 _numInterruptSources = 1; 425 426 // Set up the IOInterruptSource to point at this. 427 parentController->retain(); 428 parentSource->retain(); 429 _interruptSources[0].interruptController = parentController; 430 _interruptSources[0].vectorData = parentSource; 431 432 sourceIsLevel = false; 433 error = provider->getInterruptType(0, &interruptType); 434 if (error == kIOReturnSuccess) { 435 if (interruptType & kIOInterruptTypeLevel) 436 sourceIsLevel = true; 437 } 438 439 // Allocate the memory for the vectors 440 numVectors = kIOSharedInterruptControllerDefaultVectors; // For now a constant number. 441 vectors = (IOInterruptVector *)IOMalloc(numVectors * sizeof(IOInterruptVector)); 442 if (vectors == NULL) { 443 IOFree(_interruptSources, sizeof(IOInterruptSource)); 444 return kIOReturnNoMemory; 445 } 446 bzero(vectors, numVectors * sizeof(IOInterruptVector)); 447 448 // Allocate the lock for the controller. 449 controllerLock = IOSimpleLockAlloc(); 450 if (controllerLock == 0) return kIOReturnNoResources; 451 452 // Allocate locks for the vectors. 453 for (cnt = 0; cnt < numVectors; cnt++) { 454 vectors[cnt].interruptLock = IOLockAlloc(); 455 if (vectors[cnt].interruptLock == NULL) { 456 for (cnt = 0; cnt < numVectors; cnt++) { 457 if (vectors[cnt].interruptLock != NULL) 458 IOLockFree(vectors[cnt].interruptLock); 459 } 460 return kIOReturnNoResources; 461 } 462 } 463 464 numVectors = 0; // reset the high water mark for used vectors 465 vectorsRegistered = 0; 466 vectorsEnabled = 0; 467 controllerDisabled = 1; 468 469 return kIOReturnSuccess; 470} 471 472IOReturn IOSharedInterruptController::registerInterrupt(IOService *nub, 473 int source, 474 void *target, 475 IOInterruptHandler handler, 476 void *refCon) 477{ 478 IOInterruptSource *interruptSources; 479 IOInterruptVectorNumber vectorNumber; 480 IOInterruptVector *vector = 0; 481 OSData *vectorData; 482 IOInterruptState interruptState; 483 484 interruptSources = nub->_interruptSources; 485 486 // Find a free vector. 487 vectorNumber = kIOSharedInterruptControllerDefaultVectors; 488 while (vectorsRegistered != kIOSharedInterruptControllerDefaultVectors) { 489 for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) { 490 vector = &vectors[vectorNumber]; 491 492 // Get the lock for this vector. 493 IOLockLock(vector->interruptLock); 494 495 // Is it unregistered? 496 if (!vector->interruptRegistered) break; 497 498 // Move along to the next one. 499 IOLockUnlock(vector->interruptLock); 500 } 501 502 if (vectorNumber != kIOSharedInterruptControllerDefaultVectors) break; 503 } 504 505 // Could not find a free one, so give up. 506 if (vectorNumber == kIOSharedInterruptControllerDefaultVectors) { 507 return kIOReturnNoResources; 508 } 509 510 // Create the vectorData for the IOInterruptSource. 511 vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber)); 512 if (vectorData == 0) { 513 return kIOReturnNoMemory; 514 } 515 516 // Fill in the IOInterruptSource with the controller's info. 517 interruptSources[source].interruptController = this; 518 interruptSources[source].vectorData = vectorData; 519 520 // Fill in vector with the client's info. 521 vector->handler = handler; 522 vector->nub = nub; 523 vector->source = source; 524 vector->target = target; 525 vector->refCon = refCon; 526 527 // Get the vector ready. It starts off soft disabled. 528 vector->interruptDisabledSoft = 1; 529 vector->interruptRegistered = 1; 530 531 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 532 // Move the high water mark if needed 533 if (++vectorsRegistered > numVectors) numVectors = vectorsRegistered; 534 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); 535 536 IOLockUnlock(vector->interruptLock); 537 return kIOReturnSuccess; 538} 539 540IOReturn IOSharedInterruptController::unregisterInterrupt(IOService *nub, 541 int source) 542{ 543 IOInterruptVectorNumber vectorNumber; 544 IOInterruptVector *vector; 545 IOInterruptState interruptState; 546 547 for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) { 548 vector = &vectors[vectorNumber]; 549 550 // Get the lock for this vector. 551 IOLockLock(vector->interruptLock); 552 553 // Return success if it is not already registered 554 if (!vector->interruptRegistered 555 || (vector->nub != nub) || (vector->source != source)) { 556 IOLockUnlock(vector->interruptLock); 557 continue; 558 } 559 560 // Soft disable the source and the controller too. 561 disableInterrupt(nub, source); 562 563 // Clear all the storage for the vector except for interruptLock. 564 vector->interruptActive = 0; 565 vector->interruptDisabledSoft = 0; 566 vector->interruptDisabledHard = 0; 567 vector->interruptRegistered = 0; 568 vector->nub = 0; 569 vector->source = 0; 570 vector->handler = 0; 571 vector->target = 0; 572 vector->refCon = 0; 573 574 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 575 vectorsRegistered--; 576 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); 577 578 // Move along to the next one. 579 IOLockUnlock(vector->interruptLock); 580 } 581 582 // Re-enable the controller if all vectors are enabled. 583 if (vectorsEnabled == vectorsRegistered) { 584 controllerDisabled = 0; 585 provider->enableInterrupt(0); 586 } 587 588 return kIOReturnSuccess; 589} 590 591IOReturn IOSharedInterruptController::getInterruptType(IOService */*nub*/, 592 int /*source*/, 593 int *interruptType) 594{ 595 return provider->getInterruptType(0, interruptType); 596} 597 598IOReturn IOSharedInterruptController::enableInterrupt(IOService *nub, 599 int source) 600{ 601 IOInterruptSource *interruptSources; 602 IOInterruptVectorNumber vectorNumber; 603 IOInterruptVector *vector; 604 OSData *vectorData; 605 IOInterruptState interruptState; 606 607 interruptSources = nub->_interruptSources; 608 vectorData = interruptSources[source].vectorData; 609 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 610 vector = &vectors[vectorNumber]; 611 612 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 613 if (!vector->interruptDisabledSoft) { 614 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); 615 return kIOReturnSuccess; 616 } 617 618 vector->interruptDisabledSoft = 0; 619 vectorsEnabled++; 620 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); 621 622 if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) { 623 controllerDisabled = 0; 624 provider->enableInterrupt(0); 625 } 626 627 return kIOReturnSuccess; 628} 629 630IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub, 631 int source) 632{ 633 IOInterruptSource *interruptSources; 634 IOInterruptVectorNumber vectorNumber; 635 IOInterruptVector *vector; 636 OSData *vectorData; 637 IOInterruptState interruptState; 638 639 interruptSources = nub->_interruptSources; 640 vectorData = interruptSources[source].vectorData; 641 vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy(); 642 vector = &vectors[vectorNumber]; 643 644 interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 645 if (!vector->interruptDisabledSoft) { 646 vector->interruptDisabledSoft = 1; 647 vectorsEnabled--; 648 } 649 IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); 650 651 if (!getPlatform()->atInterruptLevel()) { 652 while (vector->interruptActive) 653 {} 654 } 655 656 return kIOReturnSuccess; 657} 658 659IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void) 660{ 661 return OSMemberFunctionCast(IOInterruptAction, 662 this, &IOSharedInterruptController::handleInterrupt); 663} 664 665IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/, 666 IOService * nub, 667 int /*source*/) 668{ 669 IOInterruptVectorNumber vectorNumber; 670 IOInterruptVector *vector; 671 672 for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) { 673 vector = &vectors[vectorNumber]; 674 675 vector->interruptActive = 1; 676 if (!vector->interruptDisabledSoft) { 677 678 // Call the handler if it exists. 679 if (vector->interruptRegistered) { 680 681 bool trace = (gIOKitTrace & kIOTraceInterrupts) ? true : false; 682 683 if (trace) 684 IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER), 685 (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target); 686 687 // Call handler. 688 vector->handler(vector->target, vector->refCon, vector->nub, vector->source); 689 690 if (trace) 691 IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER), 692 (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target); 693 694 } 695 } 696 697 vector->interruptActive = 0; 698 } 699 700 // if any of the vectors are dissabled, then dissable this controller. 701 IOSimpleLockLock(controllerLock); 702 if (vectorsEnabled != vectorsRegistered) { 703 nub->disableInterrupt(0); 704 controllerDisabled = 1; 705 } 706 IOSimpleLockUnlock(controllerLock); 707 708 return kIOReturnSuccess; 709} 710 711