1/* 2 * IOFWDCL.cpp 3 * IOFireWireFamily 4 * 5 * Created by Niels on Fri Feb 21 2003. 6 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. 7 * 8 * $ Log:IOFWDCL.cpp,v $ 9 */ 10 11#import "IOFWDCL.h" 12#import "FWDebugging.h" 13#import "IOFWUserIsochPort.h" 14 15#import "IOFireWireLibNuDCL.h" 16 17#import <libkern/c++/OSCollectionIterator.h> 18 19#if FIRELOG 20#import <IOKit/firewire/FireLog.h> 21#define FIRELOG_MSG(x) FireLog x 22#else 23#define FIRELOG_MSG(x) do {} while (0) 24#endif 25 26using namespace IOFireWireLib ; 27 28OSDefineMetaClassAndAbstractStructors( IOFWDCL, OSObject ) 29 30bool 31IOFWDCL::initWithRanges ( 32 OSSet * updateSet, 33 unsigned rangesCount, 34 IOVirtualRange ranges [] ) 35{ 36 if ( ! OSObject::init() ) 37 return false ; 38 39 if ( updateSet ) 40 { 41 updateSet->setObject( this ) ; 42 } 43 44 if ( kIOReturnSuccess != setRanges( rangesCount, ranges ) ) 45 { 46 return false ; 47 } 48 49 return true ; 50} 51 52void 53IOFWDCL::setBranch( IOFWDCL* branch ) 54{ 55 fLoLevel->lastBranch = fBranch ; 56 fBranch = branch ; 57} 58 59IOFWDCL * 60IOFWDCL::getBranch() const 61{ 62 return fBranch ; 63} 64 65void 66IOFWDCL::setTimeStampPtr ( UInt32* timeStampPtr ) 67{ 68 fTimeStampPtr = timeStampPtr ; 69} 70 71UInt32 * 72IOFWDCL::getTimeStampPtr () const 73{ 74 return (UInt32*)fTimeStampPtr ; 75} 76 77void 78IOFWDCL::setCallback( Callback callback ) 79{ 80 fCallback = callback ; 81} 82 83IOFWDCL::Callback 84IOFWDCL::getCallback() const 85{ 86 return fCallback ; 87} 88 89void 90IOFWDCL::setStatusPtr( UInt32* statusPtr ) 91{ 92 fUserStatusPtr = statusPtr ; 93} 94 95UInt32* 96IOFWDCL::getStatusPtr() const 97{ 98 return (UInt32*) fUserStatusPtr ; 99} 100 101void 102IOFWDCL::setRefcon( void * refcon ) 103{ 104 fRefcon = refcon ; 105} 106 107void * 108IOFWDCL::getRefcon() const 109{ 110 return fRefcon ; 111} 112 113const OSSet * 114IOFWDCL::getUpdateList() const 115{ 116 return fUpdateList ; 117} 118 119IOReturn 120IOFWDCL::addRange ( IOVirtualRange & range ) 121{ 122 IOVirtualRange * newRanges = new IOVirtualRange[ fRangeCount + 1 ] ; 123 if ( !newRanges ) 124 { 125 return kIOReturnNoMemory ; 126 } 127 128 bcopy( fRanges, newRanges, sizeof( IOVirtualRange ) * fRangeCount ) ; 129 delete[] fRanges ; 130 131 fRanges = newRanges ; 132 fRanges[ fRangeCount ] = range ; 133 ++fRangeCount ; 134 135 return kIOReturnSuccess ; 136} 137 138IOReturn 139IOFWDCL::setRanges ( UInt32 numRanges, IOVirtualRange ranges[] ) 140{ 141 delete[] fRanges ; 142 143 fRanges = ( numRanges && ranges ) ? new IOVirtualRange[ numRanges ] : NULL ; 144 145 if ( !fRanges ) 146 { 147 return kIOReturnNoMemory ; 148 } 149 150 bcopy( ranges, fRanges, numRanges * sizeof( IOVirtualRange ) ) ; 151 fRangeCount = numRanges ; 152 153 return kIOReturnSuccess ; 154} 155 156UInt32 157IOFWDCL::getRanges( UInt32 maxRanges, IOVirtualRange ranges[] ) const 158{ 159 unsigned count = min( maxRanges, fRangeCount ) ; 160 for( unsigned index=0; index < count; ++index ) 161 { 162 ranges[ index ] = fRanges[ index ] ; 163 } 164 165 return count ; 166} 167 168UInt32 169IOFWDCL::countRanges() 170{ 171 return fRangeCount ; 172} 173 174IOReturn 175IOFWDCL::getSpan( IOVirtualRange& result ) const 176{ 177 if ( fRangeCount == 0 ) 178 { 179 result.address = 0 ; 180 result.length = 0 ; 181 return kIOReturnSuccess ; 182 } 183 184 IOVirtualAddress lowAddress = fRanges[0].address ; 185 IOVirtualAddress highAddress = lowAddress + fRanges[0].length ; 186 187 for( unsigned index=1; index < fRangeCount; ++index ) 188 { 189 lowAddress = min( fRanges[index].address, lowAddress ) ; 190 highAddress = min( lowAddress + fRanges[ index ].length, highAddress ) ; 191 } 192 193 result.address = lowAddress ; 194 result.length = highAddress - lowAddress ; 195 196 return kIOReturnSuccess ; 197} 198 199IOByteCount 200IOFWDCL::getSize() const 201{ 202 IOByteCount size = 0 ; 203 for( unsigned index=0; index < fRangeCount; ++index ) 204 size += fRanges[ index ].length ; 205 206 return size ; 207} 208 209IOReturn 210IOFWDCL::setUpdateList( OSSet* updateList ) 211{ 212 if ( updateList ) 213 { 214 updateList->retain() ; 215 } 216 217 if ( fUpdateList ) 218 { 219 fUpdateList->release() ; 220 fUpdateList = NULL ; 221 } 222 223 if ( fUpdateIterator ) 224 { 225 fUpdateIterator->release() ; 226 fUpdateIterator = NULL ; 227 } 228 229 if ( updateList ) 230 { 231 fUpdateList = updateList ; 232 fUpdateIterator = OSCollectionIterator::withCollection( fUpdateList ) ; 233 } 234 235 return kIOReturnSuccess ; 236} 237 238void 239IOFWDCL::setFlags( UInt32 flags ) 240{ 241 fFlags = flags ; 242} 243 244UInt32 245IOFWDCL::getFlags() const 246{ 247 return fFlags ; 248} 249 250void 251IOFWDCL::debug() 252{ 253 if ( fBranch ) 254 { 255 FIRELOG_MSG(( " branch --> %p\n", fBranch )) ; 256 } 257 258 if ( fCallback ) 259 { 260 if ( fCallback == IOFWUserLocalIsochPort::s_nuDCLCallout ) 261 { 262 #if FIRELOG 263 uint64_t * asyncRef = (uint64_t*)getRefcon() ; 264 FIRELOG_MSG(( " callback (USER) callback=%p refcon=%p\n", asyncRef[ kIOAsyncCalloutFuncIndex ], asyncRef[ kIOAsyncCalloutRefconIndex ] )) ; 265 #endif 266 } 267 else 268 { 269 FIRELOG_MSG(( " callback %p\n", fCallback )) ; 270 } 271 } 272 273 if ( fTimeStampPtr ) 274 { 275 FIRELOG_MSG(( " time stamp @ %p\n", fTimeStampPtr )) ; 276 } 277 278 if ( fRangeCount ) 279 { 280 FIRELOG_MSG(( " ranges\n" )) ; 281 for( unsigned index=0; index < fRangeCount; ++index ) 282 { 283 FIRELOG_MSG(( " %d: %p ( +%dd, +0x%x )\n", index, fRanges[index].address, fRanges[index].length, fRanges[index].length )) ; 284 } 285 } 286 287 if ( fUpdateList ) 288 { 289 FIRELOG_MSG(( " update" )) ; 290 OSIterator * iterator = OSCollectionIterator::withCollection( fUpdateList ) ; 291 292 if ( !iterator ) 293 { 294 FIRELOG_MSG(("couldn't get iterator!\n")) ; 295 } 296 else 297 { 298#if FIRELOG 299 // bracket this to hide unused variable warning 300 unsigned count = 0 ; 301 while( OSObject * obj = iterator->getNextObject() ) 302 { 303 if ( ( count++ & 0x7 ) == 0 ) 304 { 305 FIRELOG_MSG(("\n" )) ; 306 FIRELOG_MSG((" ")) ; 307 } 308 FIRELOG_MSG(( "%p ", obj )) ; 309 } 310 FIRELOG_MSG(("\n")) ; 311#endif 312 iterator->release() ; 313 } 314 } 315 316 if ( fUserStatusPtr ) 317 { 318 FIRELOG_MSG(( " status @ %p\n", fUserStatusPtr )) ; 319 } 320 321 if ( fRefcon ) 322 { 323 FIRELOG_MSG(( " refcon 0x%x\n", fRefcon )) ; 324 } 325} 326 327void 328IOFWDCL::free () 329{ 330 if ( fUpdateList ) 331 { 332 fUpdateList->release() ; 333 } 334 if ( fUpdateIterator ) 335 { 336 fUpdateIterator->release() ; 337 } 338 339 if ( fCallback == IOFWUserLocalIsochPort::s_nuDCLCallout ) 340 { 341 delete [] (uint64_t*)fRefcon ; 342 } 343 344 delete[] fRanges ; 345 346 delete fLoLevel ; 347 348 OSObject::free() ; 349} 350 351void 352IOFWDCL::finalize ( IODCLProgram & ) 353{ 354 if ( fUpdateList ) 355 { 356 fUpdateList->release() ; 357 fUpdateList = NULL ; 358 } 359 360 if ( fUpdateIterator ) 361 { 362 fUpdateIterator->release() ; 363 fUpdateIterator = NULL ; 364 } 365} 366 367IOReturn 368IOFWDCL::importUserDCL ( 369 UInt8 * data, 370 IOByteCount & dataSize, 371 IOMemoryMap * bufferMap, 372 const OSArray * dcls ) 373{ 374 IOVirtualAddress kernBaseAddress = bufferMap->getVirtualAddress() ; 375 NuDCLExportData * sharedData = ( NuDCLExportData * )data ; 376 dataSize = sizeof( NuDCLExportData ) ; 377 data += dataSize ; 378 379 IOReturn error = kIOReturnSuccess ; 380 381 { 382 IOVirtualRange kernRanges[ sharedData->rangeCount ] ; 383 for( unsigned index=0; index < sharedData->rangeCount; ++index ) 384 { 385 kernRanges[ index ].address = kernBaseAddress + sharedData->ranges[ index ].address ; 386 kernRanges[ index ].length = sharedData->ranges[ index ].length ; 387 } 388 389 error = setRanges( sharedData->rangeCount, kernRanges ) ; 390 } 391 392 if ( sharedData->updateCount ) 393 { 394 // In the shared data struct for this DCL, the updateList field has 395 // been filled in with the updateList length, if any, replacing 396 // the user space CFMutableSetRef. 397 // The update list data follows the dcl shared data struct 398 // in the export data block. 399 400 uint64_t * userUpdateList = ( uint64_t * )data ; 401 dataSize += sharedData->updateCount * sizeof( uint64_t ) ; 402 403 OSSet * updateSet = OSSet::withCapacity( (unsigned)sharedData->updateCount ) ; 404 405 if ( __builtin_expect( !updateSet, false ) ) 406 { 407 error = kIOReturnNoMemory ; 408 } 409 else 410 { 411 for( unsigned index=0; index < (unsigned)sharedData->updateCount; ++index ) 412 { 413 updateSet->setObject( dcls->getObject( userUpdateList[ index ] - 1 ) ) ; 414 } 415 416 setUpdateList( updateSet ) ; 417 updateSet->release() ; 418 } 419 } 420 421 if ( !error ) 422 { 423 setFlags( IOFWDCL::kUser | sharedData->flags ) ; 424 } 425 426 if ( !error ) 427 { 428 if ( sharedData->callback ) 429 { 430 setCallback( sharedData->callback ? IOFWUserLocalIsochPort::s_nuDCLCallout : NULL ) ; 431 432 uint64_t * asyncRef = (uint64_t *) getRefcon() ; 433 434 if ( !asyncRef ) 435 { 436 asyncRef = new uint64_t[ kOSAsyncRef64Count ] ; 437 } 438 439 if ( !asyncRef ) 440 { 441 error = kIOReturnNoMemory ; 442 } 443 else 444 { 445 asyncRef[ kIOAsyncCalloutFuncIndex ] = (uint64_t)sharedData->callback ; 446 asyncRef[ kIOAsyncCalloutRefconIndex ] = (uint64_t)sharedData->refcon ; 447 448 setRefcon( asyncRef ) ; 449 } 450 } 451 else 452 { 453 if ( getCallback() == IOFWUserLocalIsochPort::s_nuDCLCallout ) 454 { 455 delete [] (uint64_t*)getRefcon() ; 456 } 457 458 setCallback( NULL ) ; 459 setRefcon( 0 ) ; 460 } 461 } 462 463 if ( !error ) 464 { 465 setTimeStampPtr( sharedData->timeStampOffset ? (UInt32*)( kernBaseAddress + sharedData->timeStampOffset - 1 ) : NULL ) ; 466 setStatusPtr( sharedData->statusOffset ? (UInt32*)( kernBaseAddress + sharedData->statusOffset - 1 ) : NULL ) ; 467 } 468 469 if ( !error ) 470 { 471 if ( sharedData->branchIndex ) 472 { 473 unsigned branchIndex = sharedData->branchIndex - 1 ; 474 if ( branchIndex >= dcls->getCount() ) 475 { 476 DebugLog("branch index out of range\n") ; 477 error = kIOReturnBadArgument ; 478 } 479 else 480 { 481 setBranch( (IOFWDCL*)dcls->getObject( branchIndex ) ) ; 482 } 483 } 484 else 485 { 486 setBranch( NULL ) ; 487 } 488 } 489 490 return error ; 491} 492 493OSMetaClassDefineReservedUsed ( IOFWDCL, 0 ) ; 494OSMetaClassDefineReservedUnused ( IOFWDCL, 1 ) ; 495OSMetaClassDefineReservedUnused ( IOFWDCL, 2 ) ; 496OSMetaClassDefineReservedUnused ( IOFWDCL, 3 ) ; 497OSMetaClassDefineReservedUnused ( IOFWDCL, 4 ) ; // used to be relink() 498 499#pragma mark - 500 501OSDefineMetaClassAndAbstractStructors( IOFWReceiveDCL, IOFWDCL ) 502 503bool 504IOFWReceiveDCL:: initWithParams( 505 OSSet * updateSet, 506 UInt8 headerBytes, 507 unsigned rangesCount, 508 IOVirtualRange ranges[] ) 509{ 510 // can only get 0, 1, or 2 header quads... 511 if (!( headerBytes == 0 || headerBytes == 4 || headerBytes == 8 ) ) 512 { 513 DebugLog("receive DCL header bytes must be 0, 4, or 8\n") ; 514 return false ; 515 } 516 517 fHeaderBytes = headerBytes ; 518 519 return IOFWDCL::initWithRanges( updateSet, rangesCount, ranges ) ; 520} 521 522 523IOReturn 524IOFWReceiveDCL::setWaitControl( bool wait ) 525{ 526 fWait = wait ; 527 return kIOReturnSuccess ; 528} 529 530void 531IOFWReceiveDCL::debug () 532{ 533 FIRELOG_MSG(("%p: RECEIVE\n", this )) ; 534 FIRELOG_MSG((" wait: %s, headerBytes: %d\n", fWait ? "YES" : "NO", fHeaderBytes )) ; 535 536 IOFWDCL::debug() ; 537} 538 539IOReturn 540IOFWReceiveDCL::importUserDCL ( 541 UInt8 * data, 542 IOByteCount & dataSize, 543 IOMemoryMap * bufferMap, 544 const OSArray * dcls ) 545{ 546 IOReturn error = IOFWDCL::importUserDCL( data, dataSize, bufferMap, dcls ) ; 547 548 if ( !error ) 549 { 550 ReceiveNuDCLExportData * rcvData = (ReceiveNuDCLExportData*)( data + dataSize ) ; 551 dataSize += sizeof( ReceiveNuDCLExportData ) ; 552 553 error = setWaitControl( rcvData->wait ) ; 554 } 555 556 return error ; 557} 558 559#pragma mark - 560 561OSDefineMetaClassAndAbstractStructors( IOFWSendDCL, IOFWDCL ) 562 563void 564IOFWSendDCL::free() 565{ 566 if ( fSkipCallback == IOFWUserLocalIsochPort::s_nuDCLCallout ) 567 { 568 delete[] (uint64_t*)fSkipRefcon ; 569 } 570 571 IOFWDCL::free() ; 572} 573 574bool 575IOFWSendDCL::initWithParams ( 576 OSSet * updateSet, 577 unsigned rangesCount, 578 IOVirtualRange ranges[], 579 UInt8 sync, 580 UInt8 tag ) 581{ 582 if ( !IOFWDCL::initWithRanges( updateSet, rangesCount, ranges ) ) 583 return false ; 584 585 fSync = sync ; 586 fTag = tag ; 587 588 return true ; 589} 590 591IOReturn 592IOFWSendDCL::addRange ( IOVirtualRange & range ) 593{ 594 if ( fRangeCount >= 5 ) 595 return kIOReturnError ; 596 597 return IOFWDCL::addRange( range ) ; 598} 599 600void 601IOFWSendDCL::setUserHeaderPtr( UInt32* userHeaderPtr, UInt32 * maskPtr ) 602{ 603 fUserHeaderPtr = userHeaderPtr ; 604 fUserHeaderMaskPtr = maskPtr ; 605} 606 607UInt32 * 608IOFWSendDCL::getUserHeaderPtr() 609{ 610 return fUserHeaderPtr ; 611} 612 613UInt32 * 614IOFWSendDCL::getUserHeaderMask() 615{ 616 return fUserHeaderMaskPtr ; 617} 618 619void 620IOFWSendDCL::setSkipBranch( IOFWDCL * skipBranchDCL ) 621{ 622 fSkipBranchDCL = skipBranchDCL ; 623} 624 625IOFWDCL * 626IOFWSendDCL::getSkipBranch() const 627{ 628 return fSkipBranchDCL ; 629} 630 631void 632IOFWSendDCL::setSkipCallback( Callback callback ) 633{ 634 fSkipCallback = callback ; 635} 636 637void 638IOFWSendDCL::setSkipRefcon( void * refcon ) 639{ 640 fSkipRefcon = refcon ; 641} 642 643IOFWDCL::Callback 644IOFWSendDCL::getSkipCallback() const 645{ 646 return fSkipCallback ; 647} 648 649void * 650IOFWSendDCL::getSkipRefcon() const 651{ 652 return fSkipRefcon ; 653} 654 655void 656IOFWSendDCL::setSync( UInt8 sync ) 657{ 658 fSync = sync ; 659} 660 661UInt8 662IOFWSendDCL::getSync() const 663{ 664 return fSync ; 665} 666 667void 668IOFWSendDCL::setTag( UInt8 tag ) 669{ 670 fTag = tag ; 671} 672 673UInt8 674IOFWSendDCL::getTag() const 675{ 676 return fTag ; 677} 678 679IOReturn 680IOFWSendDCL::setRanges ( UInt32 numRanges, IOVirtualRange ranges[] ) 681{ 682 if ( numRanges > 5 ) 683 { 684 DebugLog( "can't build send DCL with more than 5 ranges\n" ) ; 685 return kIOReturnBadArgument ; 686 } 687 688 return IOFWDCL::setRanges( numRanges, ranges ) ; 689} 690 691void 692IOFWSendDCL::debug () 693{ 694 FIRELOG_MSG(("%p: SEND\n", this )) ; 695 if ( fUserHeaderPtr ) 696 { 697 FIRELOG_MSG((" user hdr: %p, user hdr mask --> %p\n", fUserHeaderPtr, fUserHeaderMaskPtr )) ; 698 } 699 700 if ( fSkipBranchDCL ) 701 { 702 FIRELOG_MSG((" skip --> %p\n", fSkipBranchDCL )) ; 703 } 704 705 if ( fSkipCallback ) 706 { 707 if ( fSkipCallback == IOFWUserLocalIsochPort::s_nuDCLCallout ) 708 { 709 FIRELOG_MSG((" skip callback: (USER) " )) ; 710 711 if ( fSkipRefcon ) 712 { 713 FIRELOG_MSG(("callback:%p refcon:0x%lx\n", ((uint64_t*)fSkipRefcon)[ kIOAsyncCalloutFuncIndex ], ((uint64_t*)fSkipRefcon)[ kIOAsyncCalloutRefconIndex ] )) ; 714 } 715 else 716 { 717 FIRELOG_MSG(("NULL\n")) ; 718 } 719 } 720 else 721 { 722 FIRELOG_MSG((" skip callback: %p\n", fSkipCallback )) ; 723 FIRELOG_MSG((" skip refcon: 0x%lx\n", fSkipRefcon )) ; 724 } 725 } 726 727 IOFWDCL::debug() ; 728} 729 730IOReturn 731IOFWSendDCL::importUserDCL ( 732 UInt8 * data, 733 IOByteCount & dataSize, 734 IOMemoryMap * bufferMap, 735 const OSArray * dcls ) 736{ 737 IOReturn error = IOFWDCL::importUserDCL( data, dataSize, bufferMap, dcls ) ; 738 if ( error ) 739 { 740 return error ; 741 } 742 743 SendNuDCLExportData * sendData = (SendNuDCLExportData*) ( data + dataSize ) ; 744 dataSize += sizeof( SendNuDCLExportData ) ; 745 746 { 747 setSync( sendData->syncBits ) ; 748 setTag( sendData->tagBits ) ; 749 } 750 751 { 752 UInt32 * userHeaderPtr = NULL ; 753 UInt32 * userHeaderMaskPtr = NULL ; 754 755 if ( sendData->userHeaderOffset && sendData->userHeaderMaskOffset ) 756 { 757 IOVirtualAddress kernBaseAddress = bufferMap->getVirtualAddress() ; 758 759 userHeaderPtr = (UInt32*)( kernBaseAddress + sendData->userHeaderOffset - 1 ) ; 760 userHeaderMaskPtr = (UInt32*)( kernBaseAddress + sendData->userHeaderMaskOffset - 1 ) ; 761 } 762 763 setUserHeaderPtr( userHeaderPtr, userHeaderMaskPtr ) ; 764 } 765 766 if ( sendData->skipBranchIndex ) 767 { 768 unsigned branchIndex = sendData->skipBranchIndex - 1 ; 769 if ( branchIndex >= dcls->getCount() ) 770 { 771 DebugLog("skip branch index out of range\n") ; 772 error = kIOReturnBadArgument ; 773 } 774 else 775 { 776 setSkipBranch( (IOFWDCL*)dcls->getObject( branchIndex ) ) ; 777 } 778 } 779 else 780 { 781 setSkipBranch( NULL ) ; 782 } 783 784 { 785 if ( sendData->skipCallback ) 786 { 787 setSkipCallback( sendData->skipCallback ? IOFWUserLocalIsochPort::s_nuDCLCallout : NULL ) ; 788 789 uint64_t * asyncRef = (uint64_t *) getSkipRefcon() ; 790 791 if ( !asyncRef ) 792 { 793 asyncRef = new uint64_t[ kOSAsyncRef64Count ] ; 794 } 795 796 if ( !asyncRef ) 797 { 798 error = kIOReturnNoMemory ; 799 } 800 else 801 { 802 asyncRef[ kIOAsyncCalloutFuncIndex ] = (uint64_t)sendData->skipCallback ; 803 asyncRef[ kIOAsyncCalloutRefconIndex ] = (uint64_t)sendData->skipRefcon ; 804 805 setSkipRefcon( asyncRef ) ; 806 } 807 } 808 else 809 { 810 if ( getSkipCallback() == IOFWUserLocalIsochPort::s_nuDCLCallout ) 811 { 812 delete [] (uint64_t*)getSkipRefcon() ; 813 } 814 815 setSkipCallback( NULL ) ; 816 setSkipRefcon( 0 ) ; 817 } 818 } 819 820 821 return kIOReturnSuccess ; 822} 823 824#pragma mark - 825 826OSDefineMetaClassAndAbstractStructors( IOFWSkipCycleDCL, IOFWDCL ) 827 828bool 829IOFWSkipCycleDCL::init () 830{ 831 bool result = IOFWDCL::initWithRanges( NULL, 0, NULL ) ; 832 833 return result ; 834} 835 836IOReturn 837IOFWSkipCycleDCL::addRange ( IOVirtualRange& range ) 838{ 839 return kIOReturnUnsupported ; 840} 841 842IOReturn 843IOFWSkipCycleDCL::setRanges ( UInt32 numRanges, IOVirtualRange ranges[] ) 844{ 845 if ( numRanges == 0 ) 846 { 847 // init always calls setRanges.. for this DCL we will be called with 0 ranges, which 848 // is okay, so return success ; 849 850 return kIOReturnSuccess ; 851 } 852 return kIOReturnUnsupported ; 853} 854 855IOReturn 856IOFWSkipCycleDCL::getSpan ( IOVirtualRange& result ) 857{ 858 return kIOReturnUnsupported ; 859} 860 861void 862IOFWSkipCycleDCL::debug () 863{ 864 FIRELOG_MSG(("%p: SKIP CYCLE\n", this )) ; 865 IOFWDCL::debug() ; 866} 867