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