1/* 2 * IOFireWireLibDevice.cpp 3 * IOFireWireFamily 4 * 5 * Created by Niels on Thu Feb 27 2003. 6 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. 7 * 8 * $ Log:IOFireWireLibDevice.cpp,v $ 9 */ 10 11#import "IOFireWireLibDevice.h" 12#import "IOFireWireLibCommand.h" 13#import "IOFireWireLibUnitDirectory.h" 14#import "IOFireWireLibConfigDirectory.h" 15#import "IOFireWireLibPhysicalAddressSpace.h" 16#import "IOFireWireLibPseudoAddressSpace.h" 17#import "IOFireWireLibIsochChannel.h" 18#import "IOFireWireLibIsochPort.h" 19#import "IOFireWireLibDCLCommandPool.h" 20#import "IOFireWireLibNuDCLPool.h" 21#import "IOFireWireLibAsyncStreamListener.h" 22#import "IOFireWireLibIRMAllocation.h" 23#import "IOFireWireLibVectorCommand.h" 24#import "IOFireWireLibPHYPacketListener.h" 25 26#import <IOKit/iokitmig.h> 27#import <mach/mach.h> 28#import <System/libkern/OSCrossEndian.h> 29 30namespace IOFireWireLib { 31 32 Device::Device( const IUnknownVTbl & interface, CFDictionaryRef /*propertyTable*/, io_service_t service ) 33 : IOFireWireIUnknown( interface ) 34 { 35 if ( !service ) 36 throw kIOReturnBadArgument ; 37 38 // mr. safety says, "initialize for safety!" 39 mConnection = nil ; 40 mIsInited = false ; 41 mIsOpen = false ; 42 mNotifyIsOn = false ; 43 mAsyncPort = 0 ; 44 mAsyncCFPort = 0 ; 45 mBusResetHandler = 0 ; 46 mBusResetDoneHandler = 0 ; 47 48 mRunLoop = 0 ; 49 mRunLoopSource = 0 ; 50 mRunLoopMode = 0 ; 51 52 mIsochRunLoop = 0 ; 53 mIsochRunLoopSource = 0 ; 54 mIsochRunLoopMode = 0 ; 55 56 // 57 // isoch related 58 // 59 mIsochAsyncPort = 0 ; 60 mIsochAsyncCFPort = 0 ; 61 62 mDefaultDevice = service ; 63 64 IOReturn error = OpenDefaultConnection() ; 65 if ( error ) 66 throw error ; 67 68 // factory counting 69 ::CFPlugInAddInstanceForFactory( kIOFireWireLibFactoryID ); 70 71 mIsInited = true ; 72 } 73 74 Device::~Device() 75 { 76 if (mIsOpen) 77 Close() ; 78 79 if (mRunLoopSource) 80 { 81 RemoveDispatcherFromRunLoop( mRunLoop, mRunLoopSource, mRunLoopMode ) ; 82 83 CFRelease( mRunLoopSource ) ; 84 CFRelease( mRunLoop ) ; 85 CFRelease( mRunLoopMode ) ; 86 } 87 88 if ( mIsochRunLoopSource ) 89 { 90 RemoveDispatcherFromRunLoop( mIsochRunLoop, mIsochRunLoopSource, mIsochRunLoopMode ) ; 91 92 CFRelease( mIsochRunLoopSource ) ; 93 CFRelease( mIsochRunLoop ) ; 94 CFRelease( mIsochRunLoopMode ) ; 95 } 96 97 // club ports to death 98 if ( mIsochAsyncCFPort ) 99 { 100 CFMachPortInvalidate( mIsochAsyncCFPort ) ; 101 CFRelease( mIsochAsyncCFPort ) ; 102 mach_port_destroy( mach_task_self(), mIsochAsyncPort ) ; 103 } 104 105 // club ports to death 106 if ( mAsyncCFPort ) 107 { 108 CFMachPortInvalidate( mAsyncCFPort ) ; 109 CFRelease( mAsyncCFPort ) ; 110 mach_port_destroy( mach_task_self(), mAsyncPort ) ; 111 } 112 113 if ( mConnection ) 114 { 115 IOServiceClose( mConnection ) ; 116 } 117 118 if (mIsInited) 119 { 120 // factory counting 121 ::CFPlugInRemoveInstanceForFactory( kIOFireWireLibFactoryID ); 122 } 123 } 124 125 HRESULT STDMETHODCALLTYPE 126 Device::QueryInterface(REFIID iid, LPVOID* ppv) 127 { 128 HRESULT result = S_OK ; 129 *ppv = nil ; 130 131 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; 132 133 if ( CFEqual(interfaceID, kIOFireWireDeviceInterfaceID ) 134 135 // v2 interfaces... 136 || CFEqual(interfaceID, kIOFireWireDeviceInterfaceID_v2) 137 || CFEqual(interfaceID, kIOFireWireNubInterfaceID) 138 || CFEqual(interfaceID, kIOFireWireUnitInterfaceID) 139 140 // v3 interfaces... 141 || CFEqual( interfaceID, kIOFireWireNubInterfaceID_v3 ) 142 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v3 ) 143 || CFEqual( interfaceID, kIOFireWireUnitInterfaceID_v3 ) 144 145 // v4 interfaces... 146 || CFEqual( interfaceID, kIOFireWireNubInterfaceID_v4 ) 147 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v4 ) 148 || CFEqual( interfaceID, kIOFireWireUnitInterfaceID_v4 ) 149 150 // v5 interfaces... 151 || CFEqual( interfaceID, kIOFireWireNubInterfaceID_v5 ) 152 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v5 ) 153 || CFEqual( interfaceID, kIOFireWireUnitInterfaceID_v5 ) 154 155 // v6 156 157 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v6 ) 158 159 // v7 160 161 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v7 ) 162 163 // v8 164 165 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v8 ) 166 167 // v9 168 169 || CFEqual( interfaceID, kIOFireWireDeviceInterfaceID_v9 ) 170 ) 171 { 172 *ppv = & GetInterface() ; 173 AddRef() ; 174 } 175 else 176 { 177 *ppv = nil ; 178 result = E_NOINTERFACE ; 179 } 180 181 CFRelease(interfaceID) ; 182 183 return result ; 184 } 185 186#pragma mark - 187 IOReturn 188 Device::OpenDefaultConnection() 189 { 190 io_connect_t connection = 0 ; 191 IOReturn kr = kIOReturnSuccess ; 192 193 if ( 0 == mDefaultDevice ) 194 kr = kIOReturnNoDevice ; 195 196 if (kIOReturnSuccess == kr ) 197 kr = IOServiceOpen(mDefaultDevice, mach_task_self(), kIOFireWireLibConnection, & connection) ; 198 199 if (kIOReturnSuccess == kr ) 200 mConnection = connection ; 201 202 return kr ; 203 } 204 205 IOReturn 206 Device::CreateAsyncPorts() 207 { 208 IOReturn result = kIOReturnSuccess ; 209 210 if (! mAsyncPort) 211 { 212 IOCreateReceivePort(kOSAsyncCompleteMessageID, & mAsyncPort) ; 213 214 Boolean shouldFreeInfo ; 215 CFMachPortContext cfPortContext = {1, this, NULL, NULL, NULL} ; 216 mAsyncCFPort = CFMachPortCreateWithPort( 217 kCFAllocatorDefault, 218 mAsyncPort, 219 (CFMachPortCallBack) IODispatchCalloutFromMessage, 220 & cfPortContext, 221 & shouldFreeInfo) ; 222 223 if (!mAsyncCFPort) 224 result = kIOReturnNoMemory ; 225 } 226 227 return result ; 228 } 229 230 IOReturn 231 Device::CreateIsochAsyncPorts() 232 { 233 IOReturn result = kIOReturnSuccess ; 234 235 if (! mIsochAsyncPort) 236 { 237 IOCreateReceivePort(kOSAsyncCompleteMessageID, & mIsochAsyncPort) ; 238 239 Boolean shouldFreeInfo ; 240 CFMachPortContext cfPortContext = {1, this, NULL, NULL, NULL} ; 241 mIsochAsyncCFPort = CFMachPortCreateWithPort( kCFAllocatorDefault, 242 mIsochAsyncPort, 243 (CFMachPortCallBack) IODispatchCalloutFromMessage, 244 & cfPortContext, 245 & shouldFreeInfo) ; 246 if (!mIsochAsyncCFPort) 247 result = kIOReturnNoMemory ; 248 } 249 250 return result ; 251 } 252 253 IOReturn 254 Device::Open() 255 { 256 if ( mIsOpen ) 257 { 258 return kIOReturnSuccess ; 259 } 260 261 uint32_t outputCnt = 0; 262 IOReturn result = IOConnectCallScalarMethod(GetUserClientConnection(),kOpen,NULL,0,NULL,&outputCnt); 263 264 mIsOpen = (kIOReturnSuccess == result) ; 265 266 return result ; 267 } 268 269 IOReturn 270 Device::OpenWithSessionRef(IOFireWireSessionRef session) 271 { 272 if (mIsOpen) 273 { 274 return kIOReturnSuccess ; 275 } 276 277 uint32_t outputCnt = 0; 278 279 const uint64_t inputs[1]={(const uint64_t)session}; 280 281 IOReturn result = IOConnectCallScalarMethod(GetUserClientConnection(), kOpenWithSessionRef,inputs,1,NULL,&outputCnt); 282 283 mIsOpen = (kIOReturnSuccess == result) ; 284 285 return result ; 286 } 287 288 IOReturn 289 Device::Seize( IOOptionBits flags ) // v3 290 { 291 if ( mIsOpen ) 292 { 293 DebugLog("Device::Seize: Can't call while interface is open\n") ; 294 return kIOReturnError ; 295 } 296 297 if (!mConnection) 298 return kIOReturnNoDevice ; 299 300 uint32_t outputCnt = 0; 301 const uint64_t inputs[1]={(const uint64_t)flags}; 302 IOReturn err = IOConnectCallScalarMethod(GetUserClientConnection(), kSeize,inputs,1,NULL,&outputCnt); 303 304 DebugLogCond(err, "Could not seize service! err=%x\n", err) ; 305 306 return err ; 307 } 308 309 void 310 Device::Close() 311 { 312 if (!mIsOpen) 313 { 314 DebugLog("Device::Close: interface not open\n") ; 315 return ; 316 } 317 318 uint32_t outputCnt = 0; 319 IOReturn err = kIOReturnSuccess; 320 err = IOConnectCallScalarMethod(GetUserClientConnection(),kClose,NULL,0,NULL,&outputCnt); 321 322 DebugLogCond( err, "Device::Close(): error %x returned from Close()!\n", err ) ; 323 324 mIsOpen = false ; 325 } 326 327 #pragma mark - 328 IOReturn 329 Device::AddCallbackDispatcherToRunLoopForMode( // v3+ 330 CFRunLoopRef runLoop, 331 CFStringRef runLoopMode ) 332 { 333 // if the client passes 0 as the runloop, that means 334 // we should remove the source instead of adding it. 335 336 if ( !runLoop || !runLoopMode ) 337 { 338 DebugLog("IOFireWireLibDeviceInterfaceImp::AddCallbackDispatcherToRunLoopForMode: runLoop == 0 || runLoopMode == 0\n") ; 339 return kIOReturnBadArgument ; 340 } 341 342 IOReturn result = kIOReturnSuccess ; 343 344 if (!AsyncPortsExist()) 345 result = CreateAsyncPorts() ; 346 347 if ( kIOReturnSuccess == result ) 348 { 349 CFRetain( runLoop ) ; 350 CFRetain( runLoopMode ) ; 351 352 mRunLoop = runLoop ; 353 mRunLoopSource = CFMachPortCreateRunLoopSource( 354 kCFAllocatorDefault, 355 GetAsyncCFPort(), 356 0) ; 357 mRunLoopMode = runLoopMode ; 358 359 if (!mRunLoopSource) 360 { 361 CFRelease( mRunLoop ) ; 362 mRunLoop = 0 ; 363 364 CFRelease( mRunLoopMode ) ; 365 mRunLoopMode = 0 ; 366 367 result = kIOReturnNoMemory ; 368 } 369 370 #if 1 371 372 if ( kIOReturnSuccess == result ) 373 { 374 if( !CFRunLoopSourceIsValid(mRunLoopSource) ) 375 { 376 CFRelease(mRunLoopSource); 377 378 CFMachPortInvalidate( mAsyncCFPort ); 379 CFRelease( mAsyncCFPort ); 380 381 { 382 Boolean shouldFreeInfo ; 383 CFMachPortContext cfPortContext = {1, this, NULL, NULL, NULL} ; 384 mAsyncCFPort = CFMachPortCreateWithPort( 385 kCFAllocatorDefault, 386 mAsyncPort, 387 (CFMachPortCallBack) IODispatchCalloutFromMessage, 388 & cfPortContext, 389 & shouldFreeInfo) ; 390 391 if (!mAsyncCFPort) 392 result = kIOReturnNoMemory ; 393 } 394 395 { 396 mRunLoopSource = CFMachPortCreateRunLoopSource( 397 kCFAllocatorDefault, 398 GetAsyncCFPort(), 399 0) ; 400 if (!mRunLoopSource) 401 { 402 CFRelease( mRunLoop ) ; 403 mRunLoop = 0 ; 404 405 CFRelease( mRunLoopMode ) ; 406 mRunLoopMode = 0 ; 407 408 result = kIOReturnNoMemory ; 409 } 410 } 411 412 if( !CFRunLoopSourceIsValid(mRunLoopSource) ) 413 { 414 result = kIOReturnNoResources; 415 } 416 } 417 } 418 419 #endif 420 421 if ( kIOReturnSuccess == result ) 422 CFRunLoopAddSource(mRunLoop, mRunLoopSource, mRunLoopMode ) ; 423 } 424 425 return result ; 426 } 427 428 void 429 Device::RemoveDispatcherFromRunLoop( 430 CFRunLoopRef runLoop, 431 CFRunLoopSourceRef runLoopSource, 432 CFStringRef mode) 433 { 434// if ( runLoop && runLoopSource ) 435// if (CFRunLoopContainsSource( runLoop, runLoopSource, mode )) 436// CFRunLoopRemoveSource( runLoop, runLoopSource, mode ); 437 if ( runLoopSource ) 438 { 439 CFRunLoopSourceInvalidate( runLoopSource ) ; 440 } 441 } 442 443 const Boolean 444 Device::TurnOnNotification( 445 void* callBackRefCon) 446 { 447 IOReturn result = kIOReturnSuccess ; 448 449 if ( !mConnection ) 450 result = kIOReturnNoDevice ; 451 452 if (!AsyncPortsExist()) 453 result = kIOReturnError ; // zzz need a new error type meaning "you forgot to call AddDispatcherToRunLoop" 454 455 if ( kIOReturnSuccess == result ) 456 { 457 uint64_t refrncData[kOSAsyncRef64Count]; 458 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) 0; 459 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long) 0; 460 const uint64_t inputs[2] = {(const uint64_t)& Device::BusResetHandler,(const uint64_t)callBackRefCon}; 461 uint32_t outputCnt = 0; 462 result = IOConnectCallAsyncScalarMethod(mConnection, 463 kSetAsyncRef_BusReset, 464 mAsyncPort, 465 refrncData,kOSAsyncRef64Count, 466 inputs,2, 467 NULL,&outputCnt); 468 } 469 470 if ( kIOReturnSuccess == result ) 471 { 472 uint64_t refrncData[kOSAsyncRef64Count]; 473 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) 0; 474 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long) 0; 475 const uint64_t inputs[2] = {(const uint64_t)& Device::BusResetDoneHandler,(const uint64_t)callBackRefCon}; 476 uint32_t outputCnt = 0; 477 result = IOConnectCallAsyncScalarMethod(mConnection, 478 kSetAsyncRef_BusResetDone, 479 mAsyncPort, 480 refrncData,kOSAsyncRef64Count, 481 inputs,2, 482 NULL,&outputCnt); 483 } 484 485 if ( kIOReturnSuccess == result ) 486 mNotifyIsOn = true ; 487 488 return ( kIOReturnSuccess == result ) ; 489 } 490 491 void 492 Device::TurnOffNotification() 493 { 494 IOReturn result = kIOReturnSuccess ; 495 496 // if notification isn't on, skip out. 497 if (!mNotifyIsOn) 498 return ; 499 500 if (!mConnection) 501 result = kIOReturnNoDevice ; 502 503 if ( kIOReturnSuccess == result ) 504 { 505 506 uint64_t refrncData[kOSAsyncRef64Count]; 507 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) 0; 508 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long) 0; 509 const uint64_t inputs[2] = {0,0}; 510 uint32_t outputCnt = 0; 511 result = IOConnectCallAsyncScalarMethod(mConnection, 512 kSetAsyncRef_BusReset, 513 mAsyncPort, 514 refrncData,kOSAsyncRef64Count, 515 inputs,2, 516 NULL,&outputCnt); 517 518 outputCnt = 0; 519 result = IOConnectCallAsyncScalarMethod(mConnection, 520 kSetAsyncRef_BusResetDone, 521 mAsyncPort, 522 refrncData,kOSAsyncRef64Count, 523 inputs,2, 524 NULL,&outputCnt); 525 } 526 527 mNotifyIsOn = false ; 528 } 529 530 531 const IOFireWireBusResetHandler 532 Device::SetBusResetHandler( 533 IOFireWireBusResetHandler inBusResetHandler) 534 { 535 IOFireWireBusResetHandler result = mBusResetHandler ; 536 mBusResetHandler = inBusResetHandler ; 537 538 return result ; 539 } 540 541 const IOFireWireBusResetDoneHandler 542 Device::SetBusResetDoneHandler( 543 IOFireWireBusResetDoneHandler inBusResetDoneHandler) 544 { 545 IOFireWireBusResetDoneHandler result = mBusResetDoneHandler ; 546 mBusResetDoneHandler = inBusResetDoneHandler ; 547 548 return result ; 549 } 550 551 void 552 Device::BusResetHandler( 553 void* refCon, 554 IOReturn result) 555 { 556 Device* me = IOFireWireIUnknown::InterfaceMap<Device>::GetThis(refCon) ; 557 558 if (me->mBusResetHandler) 559 (me->mBusResetHandler)( (IOFireWireLibDeviceRef)refCon, (FWClientCommandID) me) ; 560 } 561 562 void 563 Device::BusResetDoneHandler( 564 void* refCon, 565 IOReturn result) 566 { 567 Device* me = IOFireWireIUnknown::InterfaceMap<Device>::GetThis(refCon) ; 568 569 if (me->mBusResetDoneHandler) 570 (me->mBusResetDoneHandler)( (IOFireWireLibDeviceRef)refCon, (FWClientCommandID) me) ; 571 } 572 573#pragma mark - 574 IOReturn 575 Device::Read( 576 io_object_t device, 577 const FWAddress & addr, 578 void* buf, 579 UInt32* size, 580 Boolean failOnReset, 581 UInt32 generation) 582 { 583 if (!mIsOpen) 584 return kIOReturnNotOpen ; 585 if ( device != mDefaultDevice && device != 0 ) 586 return kIOReturnBadArgument ; 587 588 ReadParams params = { addr, (mach_vm_address_t)buf, *size, failOnReset, generation, device == 0 /*isAbs*/ } ; 589 590#ifndef __LP64__ 591 ROSETTA_ONLY( 592 { 593 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 594 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 595 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 596 params.buf = (mach_vm_address_t)OSSwapInt64(params.buf); 597 params.size = OSSwapInt32( params.size); 598 // params.failOnReset = params.failOnReset; 599 params.generation = OSSwapInt32( params.generation ); 600 // params.isAbs = params.isAbs; 601 } 602 ); 603#endif 604 605 size_t outputStructSize = sizeof( *size ) ; 606 IOReturn status = IOConnectCallStructMethod(mConnection, 607 kRead, 608 ¶ms,sizeof(params), 609 size,&outputStructSize); 610 611#ifndef __LP64__ 612 ROSETTA_ONLY( 613 { 614 *size = OSSwapInt32( *size ); 615 } 616 ); 617#endif 618 619 return status; 620 } 621 622 IOReturn 623 Device::ReadQuadlet( io_object_t device, const FWAddress & addr, UInt32* val, Boolean failOnReset, 624 UInt32 generation ) 625 { 626 if (!mIsOpen) 627 return kIOReturnNotOpen ; 628 if ( device != mDefaultDevice && device != 0 ) 629 return kIOReturnBadArgument ; 630 631 ReadQuadParams params = { addr, (mach_vm_address_t)val, 1, failOnReset, generation, device == 0 /*isAbs*/ } ; 632 633#ifndef __LP64__ 634 ROSETTA_ONLY( 635 { 636 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 637 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 638 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 639 params.buf = (mach_vm_address_t)OSSwapInt64(params.buf); 640 params.size = OSSwapInt32( params.size); 641 // params.failOnReset = params.failOnReset; // byte 642 params.generation = OSSwapInt32( params.generation); 643 // params.isAbs = params.isAbs; // byte 644 } 645 ); 646#endif 647 648 size_t outputStructSize = sizeof( *val ) ; 649 return IOConnectCallStructMethod(mConnection, 650 kReadQuad, 651 ¶ms,sizeof(params), 652 val,&outputStructSize); 653 } 654 655 IOReturn 656 Device::Write( 657 io_object_t device, 658 const FWAddress & addr, 659 const void* buf, 660 UInt32* size, 661 Boolean failOnReset, 662 UInt32 generation) 663 { 664 if (!mIsOpen) 665 return kIOReturnNotOpen ; 666 if ( device != mDefaultDevice && device != 0 ) 667 return kIOReturnBadArgument ; 668 669 WriteParams params = { addr, (mach_vm_address_t)buf, *size, failOnReset, generation, device == 0 /*isAbs*/ } ; 670 671#ifndef __LP64__ 672 ROSETTA_ONLY( 673 { 674 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 675 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 676 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 677 params.buf = (mach_vm_address_t)OSSwapInt64(params.buf); 678 params.size = OSSwapInt32( params.size); 679 // params.failOnReset = params.failOnReset; // byte 680 params.generation = OSSwapInt32( params.generation); 681 // params.isAbs = params.isAbs; // byte 682 } 683 ); 684#endif 685 686 size_t outputStructSize = sizeof( *size ) ; 687 IOReturn status = IOConnectCallStructMethod(mConnection, 688 kWrite, 689 ¶ms,sizeof(params), 690 size,&outputStructSize); 691 692#ifndef __LP64__ 693 ROSETTA_ONLY( 694 { 695 if ( status == kIOReturnSuccess ) 696 *size = OSSwapInt32( *size ); 697 } 698 ); 699#endif 700 701 return status; 702 } 703 704 IOReturn 705 Device::WriteQuadlet( 706 io_object_t device, 707 const FWAddress & addr, 708 const UInt32 val, 709 Boolean failOnReset, 710 UInt32 generation) 711 { 712 if (!mIsOpen) 713 return kIOReturnNotOpen ; 714 if ( device != mDefaultDevice && device != 0 ) 715 return kIOReturnBadArgument ; 716 717 WriteQuadParams params = { addr, val, failOnReset, generation, device == 0 } ; 718 719#ifndef __LP64__ 720 ROSETTA_ONLY( 721 { 722 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 723 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 724 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 725 // params.val = params.val; // data 726 // params.failOnReset = params.failOnReset; // byte 727 params.generation = OSSwapInt32( params.generation); 728 // params.isAbs = params.isAbs; // byte 729 } 730 ); 731#endif 732 733 size_t outputStructSize = 0 ; 734 return IOConnectCallStructMethod(mConnection, 735 kWriteQuad, 736 ¶ms,sizeof(params), 737 NULL,&outputStructSize); 738 } 739 740 IOReturn 741 Device::CompareSwap( 742 io_object_t device, 743 const FWAddress & addr, 744 UInt32 cmpVal, 745 UInt32 newVal, 746 Boolean failOnReset, 747 UInt32 generation) 748 { 749 if (!mIsOpen) 750 return kIOReturnNotOpen ; 751 if ( device != mDefaultDevice && device != 0 ) 752 return kIOReturnBadArgument ; 753 754 UInt32 result ; 755 CompareSwapParams params ; 756 757 params.addr = addr ; 758 *(UInt32*)¶ms.cmpVal = cmpVal ; 759 *(UInt32*)¶ms.swapVal = newVal ; 760 params.size = 1 ; 761 params.failOnReset = failOnReset ; 762 params.generation = generation ; 763 params.isAbs = device == 0 ; 764 765#ifndef __LP64__ 766 ROSETTA_ONLY( 767 { 768 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 769 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 770 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 771 // params.cmpVal = params.cmpVal; // data 772 // params.newVal = params.newVal; // data 773 params.size = OSSwapInt32( params.size); 774 // params.failOnReset = params.failOnReset; // byte 775 params.generation = OSSwapInt32( params.generation); 776 // params.isAbs = params.isAbs; // byte 777 } 778 ); 779#endif 780 781 size_t outputStructSize = sizeof(UInt32) ; 782 IOReturn error = IOConnectCallStructMethod(mConnection, 783 kCompareSwap, 784 ¶ms,sizeof(params), 785 &result,&outputStructSize); 786 787 // Make sure lock transaction succeeed by 788 // checking the expected vs actual old value! 789 if ( cmpVal != result) 790 error = kIOReturnCannotLock ; 791 792 return error; 793 } 794 795 IOReturn 796 Device::CompareSwap64( 797 io_object_t device, 798 const FWAddress & addr, 799 UInt32* expectedVal, 800 UInt32* newVal, 801 UInt32* oldVal, 802 IOByteCount size, 803 Boolean failOnReset, 804 UInt32 generation) 805 { 806 if (!mIsOpen) 807 return kIOReturnNotOpen ; 808 if ( device != mDefaultDevice && device != 0 ) 809 return kIOReturnBadArgument ; 810 811 CompareSwapParams params ; 812 813 // config params 814 params.addr = addr ; 815 if ( size==4 ) 816 { 817 *(UInt32*)¶ms.cmpVal = expectedVal[0] ; 818 *(UInt32*)¶ms.swapVal = newVal[0] ; 819 } 820 else 821 { 822 params.cmpVal = *(UInt64*)expectedVal ; 823 params.swapVal = *(UInt64*)newVal ; 824 } 825 826 params.size = size >> 2 ; 827 params.failOnReset = failOnReset ; 828 params.generation = generation ; 829 params.isAbs = device == 0 ; 830 831#ifndef __LP64__ 832 ROSETTA_ONLY( 833 { 834 params.addr.nodeID = OSSwapInt16( params.addr.nodeID ); 835 params.addr.addressHi = OSSwapInt16( params.addr.addressHi ); 836 params.addr.addressLo = OSSwapInt32( params.addr.addressLo ); 837 // params.cmpVal = params.cmpVal; // data 838 // params.newVal = params.newVal; // data 839 params.size = OSSwapInt32( params.size); 840 // params.failOnReset = params.failOnReset; // byte 841 params.generation = OSSwapInt32( params.generation); 842 // params.isAbs = params.isAbs; // byte 843 } 844 ); 845#endif 846 847 UInt64 result ; 848 849 size_t outputStructSize = sizeof(UInt64) ; 850 IOReturn error = IOConnectCallStructMethod(mConnection, 851 kCompareSwap, 852 ¶ms,sizeof(params), 853 &result,&outputStructSize); 854 855 if (size==4) 856 { 857 oldVal[0] = *(UInt32*)&result ; 858 if ( oldVal[0] != expectedVal[0] ) 859 error = kIOReturnCannotLock ; 860 } 861 else 862 { 863 *(UInt64*)oldVal = result ; 864 if ( *(UInt64*)expectedVal != result ) 865 error = kIOReturnCannotLock ; 866 } 867 868 return error ; 869 } 870 871 #pragma mark - 872 #pragma mark --- command objects ---------- 873 874 IOFireWireLibCommandRef 875 Device::CreateReadCommand( 876 io_object_t device, 877 const FWAddress& addr, 878 void* buf, 879 UInt32 size, 880 IOFireWireLibCommandCallback callback, 881 Boolean failOnReset, 882 UInt32 generation, 883 void* inRefCon, 884 REFIID iid) 885 { 886 IOFireWireLibCommandRef result = 0 ; 887 888 IUnknownVTbl** iUnknown = ReadCmd::Alloc(*this, device, addr, buf, size, callback, failOnReset, generation, inRefCon) ; 889 if (iUnknown) 890 { 891 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 892 (*iUnknown)->Release(iUnknown) ; 893 } 894 895 return result ; 896 } 897 898 IOFireWireLibCommandRef 899 Device::CreateReadQuadletCommand( 900 io_object_t device, 901 const FWAddress & addr, 902 UInt32 quads[], 903 UInt32 numQuads, 904 IOFireWireLibCommandCallback callback, 905 Boolean failOnReset, 906 UInt32 generation, 907 void* inRefCon, 908 REFIID iid) 909 { 910 IOFireWireLibCommandRef result = 0 ; 911 912 // no longer supported 913 914 return result ; 915 } 916 917 IOFireWireLibCommandRef 918 Device::CreateWriteCommand( 919 io_object_t device, 920 const FWAddress & addr, 921 void* buf, 922 UInt32 size, 923 IOFireWireLibCommandCallback callback, 924 Boolean failOnReset, 925 UInt32 generation, 926 void* inRefCon, 927 REFIID iid) 928 { 929 IOFireWireLibCommandRef result = 0 ; 930 931 IUnknownVTbl** iUnknown = WriteCmd::Alloc(*this, device, addr, buf, size, callback, failOnReset, generation, inRefCon) ; 932 if (iUnknown) 933 { 934 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 935 (*iUnknown)->Release(iUnknown) ; 936 } 937 938 return result ; 939 940 } 941 942 IOFireWireLibCommandRef 943 Device::CreateWriteQuadletCommand( 944 io_object_t device, 945 const FWAddress & addr, 946 UInt32 quads[], 947 UInt32 numQuads, 948 IOFireWireLibCommandCallback callback, 949 Boolean failOnReset, 950 UInt32 generation, 951 void* inRefCon, 952 REFIID iid) 953 { 954 IOFireWireLibCommandRef result = 0 ; 955 956 // no longer supported 957 958 return result ; 959 } 960 961 IOFireWireLibCommandRef 962 Device::CreateCompareSwapCommand( io_object_t device, const FWAddress & addr, UInt64 cmpVal, UInt64 newVal, 963 unsigned int quads, IOFireWireLibCommandCallback callback, Boolean failOnReset, UInt32 generation, 964 void* inRefCon, REFIID iid) 965 { 966 IOFireWireLibCommandRef result = 0 ; 967 968 IUnknownVTbl** iUnknown = CompareSwapCmd::Alloc( *this, device, addr, cmpVal, newVal, quads, callback, failOnReset, generation, inRefCon) ; 969 if (iUnknown) 970 { 971 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 972 (*iUnknown)->Release(iUnknown) ; 973 } 974 975 return result ; 976 } 977 978 #pragma mark - 979 IOReturn 980 Device::BusReset() 981 { 982 if (!mIsOpen) 983 return kIOReturnNotOpen ; 984 985 uint32_t outputCnt = 0; 986 return IOConnectCallScalarMethod(mConnection,kBusReset,NULL,0,NULL,&outputCnt); 987 } 988 989 IOReturn 990 Device::GetCycleTime( 991 UInt32* outCycleTime) 992 { 993 uint32_t outputCnt = 2; 994 uint64_t outputVal[2]; 995 outputVal[0] = 0; 996 outputVal[1] = 0; 997 IOReturn result = IOConnectCallScalarMethod(mConnection,kCycleTime,NULL,0,outputVal,&outputCnt); 998 *outCycleTime = outputVal[0] & 0xFFFFFFFF; 999 return result; 1000 } 1001 1002 IOReturn 1003 Device::GetCycleTimeAndUpTime( 1004 UInt32* outCycleTime, 1005 UInt64* outUpTime ) 1006 { 1007 uint32_t outputCnt = 2; 1008 uint64_t outputVal[2]; 1009 outputVal[0] = 0; 1010 outputVal[1] = 0; 1011 IOReturn result = IOConnectCallScalarMethod(mConnection,kCycleTime,NULL,0,outputVal,&outputCnt); 1012 *outCycleTime = outputVal[0] & 0xFFFFFFFF; 1013 *outUpTime = outputVal[1]; 1014 return result; 1015 } 1016 1017 IOReturn 1018 Device::GetBusCycleTime( 1019 UInt32* outBusTime, 1020 UInt32* outCycleTime) 1021 { 1022 uint32_t outputCnt = 2; 1023 uint64_t outputVal[2]; 1024 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetBusCycleTime,NULL,0,outputVal,&outputCnt); 1025 *outBusTime = outputVal[0] & 0xFFFFFFFF; 1026 *outCycleTime = outputVal[1] & 0xFFFFFFFF; 1027 return result; 1028 } 1029 1030 IOReturn 1031 Device::GetGenerationAndNodeID( 1032 UInt32* outGeneration, 1033 UInt16* outNodeID) 1034 { 1035 uint32_t outputCnt = 2; 1036 uint64_t outputVal[2]; 1037 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetGenerationAndNodeID,NULL,0,outputVal,&outputCnt); 1038 *outGeneration = outputVal[0] & 0xFFFFFFFF; 1039 *outNodeID = outputVal[1] & 0xFFFF; 1040 return result; 1041 } 1042 1043 IOReturn 1044 Device::GetLocalNodeID( 1045 UInt16* outLocalNodeID) 1046 { 1047 uint32_t outputCnt = 1; 1048 uint64_t outputVal = 0; 1049 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetLocalNodeID,NULL,0,&outputVal,&outputCnt); 1050 *outLocalNodeID = outputVal & 0xFFFF; 1051 return result; 1052 } 1053 1054 IOReturn 1055 Device::GetResetTime( 1056 AbsoluteTime* resetTime) 1057 { 1058 1059 size_t outputStructSize = sizeof(*resetTime) ; 1060 IOReturn status = IOConnectCallStructMethod(mConnection, kGetResetTime, 1061 NULL,0, 1062 resetTime,&outputStructSize); 1063 1064#ifndef __LP64__ 1065 ROSETTA_ONLY( 1066 { 1067 (*resetTime).hi = OSSwapInt32( (*resetTime).hi ); 1068 (*resetTime).lo = OSSwapInt32( (*resetTime).lo ); 1069 } 1070 ); 1071#endif 1072 1073 return status; 1074 } 1075 1076 #pragma mark - 1077 IOFireWireLibLocalUnitDirectoryRef 1078 Device::CreateLocalUnitDirectory( REFIID iid ) 1079 { 1080 IOFireWireLibLocalUnitDirectoryRef result = 0 ; 1081 1082 if (mIsOpen) 1083 { 1084 // we allocate a user space pseudo address space with the reference we 1085 // got from the kernel 1086 IUnknownVTbl** iUnknown = reinterpret_cast<IUnknownVTbl**>(LocalUnitDirectory::Alloc(*this)) ; 1087 1088 // we got a new iUnknown from the object. Query it for the interface 1089 // requested in iid... 1090 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1091 1092 // we got the interface we wanted (or at least another ref to iUnknown), 1093 // so we call iUnknown.Release() 1094 (*iUnknown)->Release(iUnknown) ; 1095 } 1096 1097 return result ; 1098 } 1099 1100 IOFireWireLibConfigDirectoryRef 1101 Device::GetConfigDirectory( 1102 REFIID iid) 1103 { 1104 IOFireWireLibConfigDirectoryRef result = 0 ; 1105 1106 // we allocate a user space config directory space with the reference we 1107 // got from the kernel 1108 IUnknownVTbl** iUnknown = reinterpret_cast<IUnknownVTbl**>(ConfigDirectoryCOM::Alloc(*this)) ; 1109 1110 // we got a new iUnknown from the object. Query it for the interface 1111 // requested in iid... 1112 if (iUnknown) 1113 { 1114 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1115 1116 // we got the interface we wanted (or at least another ref to iUnknown), 1117 // so we call iUnknown.Release() 1118 (*iUnknown)->Release(iUnknown) ; 1119 } 1120 1121 return result ; 1122 } 1123 1124 IOFireWireLibConfigDirectoryRef 1125 Device::CreateConfigDirectoryWithIOObject( 1126 io_object_t inObject, 1127 REFIID iid) 1128 { 1129 IOFireWireLibConfigDirectoryRef result = 0 ; 1130 1131 // we allocate a user space pseudo address space with the reference we 1132 // got from the kernel 1133 IUnknownVTbl** iUnknown = reinterpret_cast<IUnknownVTbl**>(ConfigDirectoryCOM::Alloc(*this, (UserObjectHandle)inObject)) ; 1134 1135 // we got a new iUnknown from the object. Query it for the interface 1136 // requested in iid... 1137 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1138 1139 // we got the interface we wanted (or at least another ref to iUnknown), 1140 // so we call iUnknown.Release() 1141 (*iUnknown)->Release(iUnknown) ; 1142 1143 return result ; 1144 } 1145 1146 IOFireWireLibPhysicalAddressSpaceRef 1147 Device::CreatePhysicalAddressSpace( 1148 UInt32 inSize, 1149 void* inBackingStore, 1150 UInt32 inFlags, 1151 REFIID iid) // flags unused 1152 { 1153 IOFireWireLibPhysicalAddressSpaceRef result = 0 ; 1154 1155 if ( mIsOpen ) 1156 { 1157 UserObjectHandle output ; 1158 uint32_t outputCnt = 1; 1159 uint64_t outputVal = 0; 1160 const uint64_t inputs[3] = {inSize, (const uint64_t)inBackingStore, inFlags}; 1161 if ( kIOReturnSuccess == IOConnectCallScalarMethod(mConnection,kPhysicalAddrSpace_Allocate,inputs,3,&outputVal,&outputCnt) ) 1162 { 1163 output = (UserObjectHandle) outputVal; 1164 if (output) 1165 { 1166 // we allocate a user space pseudo address space with the reference we 1167 // got from the kernel 1168 IUnknownVTbl** iUnknown = PhysicalAddressSpace::Alloc(*this, output, inSize, inBackingStore, inFlags) ; 1169 1170 // we got a new iUnknown from the object. Query it for the interface 1171 // requested in iid... 1172 if (iUnknown) 1173 { 1174 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1175 1176 // we got the interface we wanted (or at least another ref to iUnknown), 1177 // so we call iUnknown.Release() 1178 (*iUnknown)->Release(iUnknown) ; 1179 } 1180 } 1181 } 1182 1183 } 1184 1185 return result ; 1186 } 1187 1188 IOFireWireLibPseudoAddressSpaceRef 1189 Device::CreateAddressSpace( 1190 UInt32 inSize, 1191 void* inRefCon, 1192 UInt32 inQueueBufferSize, 1193 void* inBackingStore, 1194 UInt32 inFlags, 1195 REFIID iid, 1196 Boolean isInitialUnits, 1197 UInt32 inAddressLo ) 1198 { 1199 if (!mIsOpen) 1200 { 1201 DebugLog( "Device::CreatePseudoAddressSpace: no connection or device is not open\n") ; 1202 return 0 ; 1203 } 1204 1205 if ( !inBackingStore && ( (inFlags & kFWAddressSpaceAutoWriteReply != 0) || (inFlags & kFWAddressSpaceAutoReadReply != 0) || (inFlags & kFWAddressSpaceAutoCopyOnWrite != 0) ) ) 1206 { 1207 DebugLog( "Can't create address space with nil backing store!\n" ) ; 1208 return 0 ; 1209 } 1210 1211 IOFireWireLibPseudoAddressSpaceRef result = 0 ; 1212 1213 void* queueBuffer = nil ; 1214 if ( inQueueBufferSize > 0 ) 1215 queueBuffer = new Byte[inQueueBufferSize] ; 1216 1217 AddressSpaceCreateParams params ; 1218 params.size = inSize ; 1219 params.queueBuffer = (mach_vm_address_t) queueBuffer ; 1220 params.queueSize = (UInt32) inQueueBufferSize ; 1221 params.backingStore = (mach_vm_address_t) inBackingStore ; 1222 params.refCon = (mach_vm_address_t)this ; //zzz is this even used? 1223 params.flags = inFlags ; 1224 params.isInitialUnits = isInitialUnits ; 1225 params.addressLo = inAddressLo ; 1226 1227#ifndef __LP64__ 1228 ROSETTA_ONLY( 1229 { 1230 params.size = OSSwapInt64( params.size ); 1231 params.queueBuffer = (mach_vm_address_t)OSSwapInt64( (UInt64)params.queueBuffer ); 1232 params.queueSize = OSSwapInt64( params.queueSize ); 1233 params.backingStore = (mach_vm_address_t)OSSwapInt64( (UInt64)params.backingStore ); 1234 params.flags = OSSwapInt32( params.flags ); 1235 // params.isInitialUnits = params.isInitialUnits // byte 1236 params.addressLo = OSSwapInt32( params.addressLo ); 1237 } 1238 ); 1239#endif 1240 1241 UserObjectHandle addrSpaceRef ; 1242 1243 size_t outputStructSize = sizeof(addrSpaceRef) ; 1244 IOReturn err = IOConnectCallStructMethod(mConnection, kPseudoAddrSpace_Allocate, 1245 ¶ms,sizeof(params), 1246 & addrSpaceRef,&outputStructSize); 1247 1248#ifndef __LP64__ 1249 ROSETTA_ONLY( 1250 { 1251 addrSpaceRef = (UserObjectHandle)OSSwapInt32( (UInt32)addrSpaceRef ); 1252 } 1253 ); 1254#endif 1255 1256 if ( !err ) 1257 { 1258 // we allocate a user space pseudo address space with the reference we 1259 // got from the kernel 1260 IUnknownVTbl** iUnknown = PseudoAddressSpace::Alloc(*this, addrSpaceRef, queueBuffer, inQueueBufferSize, inBackingStore, inRefCon) ; 1261 1262 // we got a new iUnknown from the object. Query it for the interface 1263 // requested in iid... 1264 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1265 1266 // we got the interface we wanted (or at least another ref to iUnknown), 1267 // so we call iUnknown.Release() 1268 (*iUnknown)->Release(iUnknown) ; 1269 1270 } 1271 1272 return result ; 1273 } 1274 1275 1276 #pragma mark - 1277 IOReturn 1278 Device::FireBugMsg( 1279 const char * inMsg) 1280 { 1281 IOReturn result = kIOReturnSuccess ; 1282 UInt32 size = strlen(inMsg) + 1 ; 1283 1284 if (!mIsOpen) 1285 result = kIOReturnNotOpen ; 1286 1287 { 1288 UInt32 generation = 0 ; 1289 UInt16 nodeID ; 1290 1291 if ( kIOReturnSuccess == result ) 1292 result = GetGenerationAndNodeID( & generation, & nodeID ) ; 1293 1294 if (kIOReturnSuccess == result) 1295 { 1296 result = Write(0, FWAddress(0x4242, 0x42424242, 0x4242), inMsg, & size, true, generation) ; 1297 1298 // firebug never responds, so just change a timeout err into success 1299 if ( kIOReturnTimeout == result ) 1300 result = kIOReturnSuccess ; 1301 } 1302 } 1303 1304 return result ; 1305 } 1306 1307 IOReturn 1308 Device::FireLog( 1309 const char * format, 1310 va_list ap ) 1311 { 1312 char msg[128] ; 1313 vsnprintf( msg, 127, format, ap ) ; 1314 1315 size_t outputStructSize = 0 ; 1316 IOReturn err = IOConnectCallStructMethod(GetUserClientConnection(), 1317 kFireLog, 1318 msg,strlen( msg )+1, 1319 NULL,&outputStructSize); 1320 return err ; 1321 } 1322 1323 IOReturn 1324 Device::FireLog( const char* format, ... ) 1325 { 1326 IOReturn error = kIOReturnSuccess; 1327 1328 va_list ap ; 1329 va_start( ap, format ) ; 1330 1331 error = FireLog( format, ap ) ; 1332 1333 va_end( ap ) ; 1334 1335 return error ; 1336 } 1337 1338 IOReturn 1339 Device::CreateCFStringWithOSStringRef( 1340 UserObjectHandle inStringRef, 1341 UInt32 inStringLen, 1342 CFStringRef*& text) 1343 { 1344 char* textBuffer = new char[inStringLen+1] ; 1345 //io_connect_t connection = GetUserClientConnection() ; 1346 UInt32 stringSize ; 1347 1348 if (!textBuffer) 1349 return kIOReturnNoMemory ; 1350 1351 uint32_t outputCnt = 1; 1352 uint64_t outputVal = 0; 1353 const uint64_t inputs[3] = {(uint64_t)inStringRef, inStringLen, (uint64_t)textBuffer}; 1354 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetOSStringData,inputs,3,&outputVal,&outputCnt); 1355 stringSize = outputVal & 0xFFFFFFFF; 1356 1357 textBuffer[inStringLen] = 0 ; 1358 1359 if (text && (kIOReturnSuccess == result)) 1360 *text = CFStringCreateWithCString(kCFAllocatorDefault, textBuffer, kCFStringEncodingASCII) ; 1361 1362 delete[] textBuffer ; 1363 1364 return result ; 1365 } 1366 1367 IOReturn 1368 Device::CreateCFDataWithOSDataRef( 1369 UserObjectHandle inDataRef, 1370 IOByteCount inDataSize, 1371 CFDataRef*& data) 1372 { 1373 UInt8* buffer = new UInt8[inDataSize] ; 1374 IOByteCount dataSize ; 1375 1376 if (!buffer) 1377 return kIOReturnNoMemory ; 1378 1379 if (!mConnection) 1380 return kIOReturnError ; 1381 1382 uint32_t outputCnt = 1; 1383 uint64_t outputVal = 0; 1384 const uint64_t inputs[3] = {(uint64_t)inDataRef, inDataSize, (uint64_t)buffer}; 1385 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetOSDataData,inputs,3,&outputVal,&outputCnt); 1386 dataSize = outputVal & 0xFFFFFFFF; 1387 1388 if (data && (kIOReturnSuccess == result)) 1389 *data = CFDataCreate(kCFAllocatorDefault, buffer, inDataSize) ; 1390 1391 if (!data) 1392 result = kIOReturnNoMemory ; 1393 1394 delete[] buffer ; 1395 1396 return result ; 1397 } 1398 1399 // 1400 // --- isoch related 1401 // 1402 IOReturn 1403 Device::AddIsochCallbackDispatcherToRunLoopForMode( // v3+ 1404 CFRunLoopRef runLoop, 1405 CFStringRef runLoopMode ) 1406 { 1407 IOReturn result = kIOReturnSuccess ; 1408 1409 if ( !runLoop || !runLoopMode ) 1410 { 1411 DebugLog("Device::AddIsochCallbackDispatcherToRunLoopForMode: runLoop==0 || runLoopMode==0\n") ; 1412 return kIOReturnBadArgument ; 1413 } 1414 1415 if (!IsochAsyncPortsExist()) 1416 result = CreateIsochAsyncPorts() ; 1417 1418 if ( kIOReturnSuccess == result ) 1419 { 1420 CFRetain(runLoop) ; 1421 CFRetain(runLoopMode) ; 1422 1423 mIsochRunLoop = runLoop ; 1424 mIsochRunLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, 1425 GetIsochAsyncCFPort() , 1426 0) ; 1427 mIsochRunLoopMode = runLoopMode ; 1428 1429 if (!mIsochRunLoopSource) 1430 { 1431 CFRelease( mIsochRunLoop ) ; 1432 CFRelease( mIsochRunLoopMode ) ; 1433 result = kIOReturnNoMemory ; 1434 } 1435 1436 #if 1 1437 1438 if ( kIOReturnSuccess == result ) 1439 { 1440 if( !CFRunLoopSourceIsValid(mIsochRunLoopSource) ) 1441 { 1442 CFRelease( mIsochRunLoopSource ); 1443 1444 CFMachPortInvalidate( mIsochAsyncCFPort ); 1445 CFRelease( mIsochAsyncCFPort ); 1446 1447 { 1448 Boolean shouldFreeInfo; 1449 CFMachPortContext cfPortContext = {1, this, NULL, NULL, NULL}; 1450 mIsochAsyncCFPort = CFMachPortCreateWithPort( kCFAllocatorDefault, 1451 mIsochAsyncPort, 1452 (CFMachPortCallBack) IODispatchCalloutFromMessage, 1453 & cfPortContext, 1454 & shouldFreeInfo); 1455 if (!mIsochAsyncCFPort) 1456 result = kIOReturnNoMemory ; 1457 1458 } 1459 1460 { 1461 mIsochRunLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, 1462 GetIsochAsyncCFPort() , 1463 0) ; 1464 if (!mIsochRunLoopSource) 1465 { 1466 CFRelease( mIsochRunLoop ) ; 1467 CFRelease( mIsochRunLoopMode ) ; 1468 result = kIOReturnNoMemory ; 1469 } 1470 } 1471 1472 if( !CFRunLoopSourceIsValid(mIsochRunLoopSource) ) 1473 { 1474 result = kIOReturnNoResources; 1475 } 1476 } 1477 } 1478 1479 #endif 1480 1481 if ( kIOReturnSuccess == result ) 1482 ::CFRunLoopAddSource( mIsochRunLoop, mIsochRunLoopSource, mIsochRunLoopMode ) ; 1483 } 1484 1485 return result ; 1486 } 1487 1488 void 1489 Device::RemoveIsochCallbackDispatcherFromRunLoop() 1490 { 1491 RemoveDispatcherFromRunLoop( mIsochRunLoop, mIsochRunLoopSource, mIsochRunLoopMode ) ; 1492 1493 CFRelease(mIsochRunLoop) ; 1494 mIsochRunLoop = 0 ; 1495 1496 CFRelease( mIsochRunLoopSource ) ; 1497 mIsochRunLoopSource = 0 ; 1498 1499 CFRelease( mIsochRunLoopMode ); 1500 mIsochRunLoopMode = 0 ; 1501 } 1502 1503 IOFireWireLibRemoteIsochPortRef 1504 Device::CreateRemoteIsochPort( 1505 Boolean inTalking, 1506 REFIID iid) 1507 { 1508 IOFireWireLibRemoteIsochPortRef result = 0 ; 1509 1510 IUnknownVTbl** iUnknown = RemoteIsochPortCOM::Alloc(*this, inTalking) ; 1511 if (iUnknown) 1512 { 1513 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1514 (*iUnknown)->Release(iUnknown) ; 1515 } 1516 1517 return result ; 1518 } 1519 1520 IOFireWireLibLocalIsochPortRef 1521 Device::CreateLocalIsochPortWithOptions( 1522 Boolean talking, 1523 DCLCommand* dclProgram, 1524 UInt32 startEvent, 1525 UInt32 startState, 1526 UInt32 startMask, 1527 IOVirtualRange dclProgramRanges[], // optional optimization parameters 1528 UInt32 dclProgramRangeCount, 1529 IOVirtualRange bufferRanges[], 1530 UInt32 bufferRangeCount, 1531 IOFWIsochPortOptions options, 1532 REFIID iid) 1533 { 1534 IOFireWireLibLocalIsochPortRef result = 0 ; 1535 1536 IUnknownVTbl** iUnknown = LocalIsochPortCOM::Alloc(*this, talking, dclProgram, startEvent, startState, 1537 startMask, dclProgramRanges, dclProgramRangeCount, bufferRanges, bufferRangeCount, options ) ; 1538 if (iUnknown) 1539 { 1540 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1541 (*iUnknown)->Release(iUnknown) ; 1542 } 1543 1544 return result ; 1545 } 1546 1547 IOReturn 1548 Device::GetBusGeneration( UInt32* outGeneration ) 1549 { 1550 uint32_t outputCnt = 1; 1551 uint64_t outputVal = 0; 1552 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetBusGeneration,NULL,0,&outputVal,&outputCnt); 1553 *outGeneration = outputVal & 0xFFFFFFFF; 1554 return result; 1555 } 1556 1557 IOReturn 1558 Device::GetLocalNodeIDWithGeneration( UInt32 checkGeneration, UInt16* outLocalNodeID ) 1559 { 1560 uint32_t outputCnt = 1; 1561 uint64_t outputVal = 0; 1562 const uint64_t inputs[1]={(const uint64_t)checkGeneration}; 1563 1564 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetLocalNodeIDWithGeneration,inputs,1,&outputVal,&outputCnt); 1565 *outLocalNodeID = outputVal & 0xFFFF; 1566 return result; 1567 } 1568 1569 IOReturn 1570 Device::GetRemoteNodeID( UInt32 checkGeneration, UInt16* outRemoteNodeID ) 1571 { 1572 uint32_t outputCnt = 1; 1573 uint64_t outputVal = 0; 1574 const uint64_t inputs[1]={(const uint64_t)checkGeneration}; 1575 1576 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetRemoteNodeID,inputs,1,&outputVal,&outputCnt); 1577 *outRemoteNodeID = outputVal & 0xFFFF; 1578 return result; 1579 } 1580 1581 IOReturn 1582 Device::GetSpeedToNode( UInt32 checkGeneration, IOFWSpeed* outSpeed) 1583 { 1584 uint32_t outputCnt = 1; 1585 uint64_t outputVal = 0; 1586 const uint64_t inputs[1]={(const uint64_t)checkGeneration}; 1587 1588 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetSpeedToNode,inputs,1,&outputVal,&outputCnt); 1589 *outSpeed = (IOFWSpeed)(outputVal & 0xFFFFFFFF); 1590 return result; 1591 } 1592 1593 IOReturn 1594 Device::GetSpeedBetweenNodes( UInt32 checkGeneration, UInt16 srcNodeID, UInt16 destNodeID, IOFWSpeed* outSpeed) 1595 { 1596 uint32_t outputCnt = 1; 1597 uint64_t outputVal = 0; 1598 const uint64_t inputs[3] = {checkGeneration, srcNodeID, destNodeID}; 1599 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetSpeedBetweenNodes,inputs,3,&outputVal,&outputCnt); 1600 *outSpeed = (IOFWSpeed)(outputVal & 0xFFFFFFFF); 1601 return result; 1602 } 1603 1604 IOReturn 1605 Device::GetIRMNodeID( UInt32 checkGeneration, UInt16* outIRMNodeID ) 1606 { 1607 uint32_t outputCnt = 1; 1608 uint64_t outputVal = 0; 1609 const uint64_t inputs[1]={(const uint64_t)checkGeneration}; 1610 1611 IOReturn result = IOConnectCallScalarMethod(mConnection,kGetIRMNodeID,inputs,1,&outputVal,&outputCnt); 1612 *outIRMNodeID = outputVal & 0xFFFF; 1613 return result; 1614 } 1615 1616 IOReturn 1617 Device::ClipMaxRec2K( Boolean clipMaxRec ) 1618 { 1619 //fprintf(stderr, "Device::ClipMaxRec2K\n") ; 1620 1621 uint32_t outputCnt = 0; 1622 const uint64_t inputs[1]={(const uint64_t)clipMaxRec}; 1623 IOReturn result = IOConnectCallScalarMethod(mConnection,kClipMaxRec2K,inputs,1,NULL,&outputCnt); 1624 return result; 1625 } 1626 1627 IOFireWireSessionRef 1628 Device::GetSessionRef() 1629 { 1630 uint32_t outputCnt = 1; 1631 uint64_t outputVal = 0; 1632 IOReturn error = kIOReturnSuccess; 1633 error = IOConnectCallScalarMethod(mConnection,kGetSessionRef,NULL,0,&outputVal,&outputCnt); 1634 DebugLogCond( error, "Device::GetSessionRef error=%x\n", error ) ; 1635 return (IOFireWireSessionRef) outputVal; 1636 } 1637 1638 IOFireWireLibVectorCommandRef 1639 Device::CreateVectorCommand( 1640 IOFireWireLibCommandCallback callback, 1641 void* inRefCon, 1642 REFIID iid ) 1643 { 1644 IOFireWireLibVectorCommandRef result = 0; 1645 1646 IUnknownVTbl** iUnknown = VectorCommand::Alloc( *this, callback, inRefCon ); 1647 if( iUnknown ) 1648 { 1649 (*iUnknown)->QueryInterface( iUnknown, iid, (void**)&result ); 1650 (*iUnknown)->Release( iUnknown ); 1651 } 1652 1653 return result; 1654 } 1655 1656 IOFireWireLibCommandRef 1657 Device::CreatePHYCommand( 1658 UInt32 data1, 1659 UInt32 data2, 1660 IOFireWireLibCommandCallback callback, 1661 Boolean failOnReset, 1662 UInt32 generation, 1663 void* inRefCon, 1664 REFIID iid ) 1665 { 1666 IOFireWireLibCommandRef result = 0; 1667 1668 IUnknownVTbl** iUnknown = PHYCmd::Alloc( *this, data1, data2, callback, failOnReset, generation, inRefCon ); 1669 if( iUnknown ) 1670 { 1671 (*iUnknown)->QueryInterface( iUnknown, iid, (void**)&result ); 1672 (*iUnknown)->Release( iUnknown ); 1673 } 1674 1675 return result; 1676 } 1677 1678 IOFireWireLibPHYPacketListenerRef 1679 Device::CreatePHYPacketListener( 1680 UInt32 queueCount, 1681 REFIID iid ) 1682 { 1683 IOFireWireLibPHYPacketListenerRef result = 0; 1684 1685 IUnknownVTbl** iUnknown = PHYPacketListener::Alloc( *this, queueCount ); 1686 if( iUnknown ) 1687 { 1688 (*iUnknown)->QueryInterface( iUnknown, iid, (void**)&result ); 1689 (*iUnknown)->Release( iUnknown ); 1690 } 1691 1692 return result; 1693 } 1694 1695 IOReturn Device::AllocateIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation) 1696 { 1697 uint32_t outputCnt = 0; 1698 const uint64_t inputs[2]={bandwidthUnits,generation}; 1699 IOReturn result = IOConnectCallScalarMethod(mConnection,kAllocateIRMBandwidth,inputs,2,NULL,&outputCnt); 1700 return result; 1701 } 1702 1703 IOReturn Device::ReleaseIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation) 1704 { 1705 uint32_t outputCnt = 0; 1706 const uint64_t inputs[2]={bandwidthUnits,generation}; 1707 IOReturn result = IOConnectCallScalarMethod(mConnection,kReleaseIRMBandwidth,inputs,2,NULL,&outputCnt); 1708 return result; 1709 } 1710 1711 IOReturn Device::AllocateIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation) 1712 { 1713 uint32_t outputCnt = 0; 1714 const uint64_t inputs[2]={isochChannel,generation}; 1715 IOReturn result = IOConnectCallScalarMethod(mConnection,kAllocateIRMChannel,inputs,2,NULL,&outputCnt); 1716 return result; 1717 } 1718 1719 IOReturn Device::ReleaseIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation) 1720 { 1721 uint32_t outputCnt = 0; 1722 const uint64_t inputs[2]={isochChannel,generation}; 1723 IOReturn result = IOConnectCallScalarMethod(mConnection,kReleaseIRMChannel,inputs,2,NULL,&outputCnt); 1724 return result; 1725 } 1726 1727 IOFireWireLibIRMAllocationRef Device::CreateIRMAllocation(Boolean releaseIRMResourcesOnFree, 1728 IOFireWireLibIRMAllocationLostNotificationProc callback, 1729 void *pLostNotificationProcRefCon, 1730 REFIID iid) 1731 { 1732 if (!mIsOpen) 1733 { 1734 DebugLog( "Device::CreateIRMAllocation: no connection or device is not open\n") ; 1735 return 0 ; 1736 } 1737 1738 IOFireWireLibIRMAllocationRef returnInterface = 0 ; 1739 IOReturn result; 1740 const uint64_t inputs[1] = {releaseIRMResourcesOnFree}; 1741 uint32_t outputCnt = 1; 1742 uint64_t outputVal = 0; 1743 UserObjectHandle userObjectRef ; 1744 1745 result = IOConnectCallScalarMethod(mConnection, 1746 kIRMAllocation_Allocate, 1747 inputs,1, 1748 &outputVal,&outputCnt); 1749 1750 if (result == kIOReturnSuccess) 1751 { 1752 userObjectRef = (UserObjectHandle) outputVal; 1753 1754 IUnknownVTbl** iUnknown = IRMAllocationCOM::Alloc(*this, userObjectRef, (void*)callback, pLostNotificationProcRefCon) ; 1755 1756 // we got a new iUnknown from the object. Query it for the interface 1757 // requested in iid... 1758 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & returnInterface) ; 1759 1760 // we got the interface we wanted (or at least another ref to iUnknown), 1761 // so we call iUnknown.Release() 1762 (*iUnknown)->Release(iUnknown) ; 1763 } 1764 1765 return returnInterface; 1766 } 1767 1768 IOFWAsyncStreamListenerInterfaceRef Device::CreateAsyncStreamListener( UInt32 channel, 1769 IOFWAsyncStreamListenerHandler callback, 1770 void * inRefCon, 1771 UInt32 inQueueBufferSize, 1772 REFIID iid ) 1773 { 1774 if (!mIsOpen) 1775 { 1776 DebugLog( "Device::CreateAsyncStreamListener: no connection or device is not open\n") ; 1777 return 0 ; 1778 } 1779 1780 IOFWAsyncStreamListenerInterfaceRef result = 0 ; 1781 1782 void* queueBuffer = nil ; 1783 if ( inQueueBufferSize > 0 ) 1784 queueBuffer = new Byte[inQueueBufferSize] ; 1785 1786 FWUserAsyncStreamListenerCreateParams params ; 1787 1788 params.channel = channel; 1789 params.queueBuffer = (mach_vm_address_t) queueBuffer ; 1790 params.queueSize = (UInt32) inQueueBufferSize ; 1791 params.flags = 0 ; 1792 params.callback = (mach_vm_address_t)callback; 1793 params.refCon = (mach_vm_address_t)this ; 1794 1795#ifndef __LP64__ 1796 ROSETTA_ONLY( 1797 { 1798 params.channel = OSSwapInt32( params.channel ); 1799 params.queueBuffer = (mach_vm_address_t)OSSwapInt32( (UInt32)params.queueBuffer ); 1800 params.queueSize = OSSwapInt32( params.queueSize ); 1801 params.flags = OSSwapInt32( params.flags ); 1802 } 1803 ); 1804#endif 1805 1806 UserObjectHandle asyncStreamListenerRef ; 1807 1808 size_t outputStructSize = sizeof(asyncStreamListenerRef) ; 1809 IOReturn err = IOConnectCallStructMethod(mConnection, 1810 kAsyncStreamListener_Allocate, 1811 ¶ms,sizeof(params), 1812 &asyncStreamListenerRef,&outputStructSize); 1813 1814 //IOByteCount size = sizeof(asyncStreamListenerRef) ; 1815 // call the routine which creates a pseudo address space in the kernel. 1816 //IOReturn err = ::IOConnectMethodStructureIStructureO( mConnection, kAsyncStreamListener_Allocate, 1817 // sizeof(params), & size, & params, & asyncStreamListenerRef ) ; 1818 1819#ifndef __LP64__ 1820 ROSETTA_ONLY( 1821 { 1822 asyncStreamListenerRef = (UserObjectHandle)OSSwapInt32( (UInt32)asyncStreamListenerRef ); 1823 } 1824 ); 1825#endif 1826 1827 if ( !err ) 1828 { 1829 // we allocate a async stream listener with the reference we 1830 // got from the kernel 1831 IUnknownVTbl** iUnknown = AsyncStreamListenerCOM::Alloc(*this, asyncStreamListenerRef, queueBuffer, inQueueBufferSize, (void*)callback, inRefCon) ; 1832 1833 // we got a new iUnknown from the object. Query it for the interface 1834 // requested in iid... 1835 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 1836 1837 // we got the interface we wanted (or at least another ref to iUnknown), 1838 // so we call iUnknown.Release() 1839 (*iUnknown)->Release(iUnknown) ; 1840 1841 } 1842 1843 return result ; 1844 } 1845 1846 IOFireWireLibCommandRef Device::CreateAsyncStreamCommand( UInt32 channel, 1847 UInt32 sync, 1848 UInt32 tag, 1849 void* buf, 1850 UInt32 size, 1851 IOFireWireLibCommandCallback callback, 1852 Boolean failOnReset, 1853 UInt32 generation, 1854 void* inRefCon, 1855 REFIID iid) 1856 { 1857 IOFireWireLibCommandRef result = 0; 1858 1859 IUnknownVTbl** iUnknown = AsyncStreamCmd::Alloc( *this, channel, sync, tag, buf, size, callback, failOnReset, generation, inRefCon ); 1860 if( iUnknown ) 1861 { 1862 (*iUnknown)->QueryInterface( iUnknown, iid, (void**)&result ); 1863 (*iUnknown)->Release( iUnknown ); 1864 } 1865 1866 return result; 1867 } 1868 1869 1870#pragma mark - 1871 const IOFireWireDeviceInterface DeviceCOM::sInterface = 1872 { 1873 INTERFACEIMP_INTERFACE, 1874 8, 0, // version/revision 1875 1876 & DeviceCOM::SInterfaceIsInited, 1877 & DeviceCOM::SGetDevice, 1878 & DeviceCOM::SOpen, 1879 & DeviceCOM::SOpenWithSessionRef, 1880 & DeviceCOM::SClose, 1881 & DeviceCOM::SNotificationIsOn, 1882 & DeviceCOM::SAddCallbackDispatcherToRunLoop, 1883 & DeviceCOM::SRemoveCallbackDispatcherFromRunLoop, 1884 & DeviceCOM::STurnOnNotification, 1885 & DeviceCOM::STurnOffNotification, 1886 & DeviceCOM::SSetBusResetHandler, 1887 & DeviceCOM::SSetBusResetDoneHandler, 1888 & DeviceCOM::SClientCommandIsComplete, 1889 1890 // --- FireWire send/recv methods -------------- 1891 & DeviceCOM::SRead, 1892 & DeviceCOM::SReadQuadlet, 1893 & DeviceCOM::SWrite, 1894 & DeviceCOM::SWriteQuadlet, 1895 & DeviceCOM::SCompareSwap, 1896 1897 // --- firewire commands ----------------------- 1898 & DeviceCOM::SCreateReadCommand, 1899 & DeviceCOM::SCreateReadQuadletCommand, 1900 & DeviceCOM::SCreateWriteCommand, 1901 & DeviceCOM::SCreateWriteQuadletCommand, 1902 & DeviceCOM::SCreateCompareSwapCommand, 1903 1904 // --- other methods --------------------------- 1905 & DeviceCOM::SBusReset, 1906 & DeviceCOM::SGetCycleTime, 1907 & DeviceCOM::SGetGenerationAndNodeID, 1908 & DeviceCOM::SGetLocalNodeID, 1909 & DeviceCOM::SGetResetTime, 1910 1911 // --- unit directory support ------------------ 1912 & DeviceCOM::SCreateLocalUnitDirectory, 1913 1914 & DeviceCOM::SGetConfigDirectory, 1915 & DeviceCOM::SCreateConfigDirectoryWithIOObject, 1916 // --- address space support ------------------- 1917 & DeviceCOM::SCreatePseudoAddressSpace, 1918 & DeviceCOM::SCreatePhysicalAddressSpace, 1919 1920 // --- debugging ------------------------------- 1921 & DeviceCOM::SFireBugMsg, 1922 1923 // --- isoch ----------------------------------- 1924 & DeviceCOM::SAddIsochCallbackDispatcherToRunLoop, 1925 & DeviceCOM::SCreateRemoteIsochPort, 1926 & DeviceCOM::S_CreateLocalIsochPort, 1927 & DeviceCOM::SCreateIsochChannel, 1928 & DeviceCOM::SCreateDCLCommandPool, 1929 1930 // --- refcon ---------------------------------- 1931 & DeviceCOM::SGetRefCon, 1932 & DeviceCOM::SSetRefCon, 1933 1934 // --- debugging ------------------------------- 1935 // do not use this function 1936 // & DeviceCOM::SGetDebugProperty, 1937 NULL, 1938 & DeviceCOM::SPrintDCLProgram, 1939 1940 // --- initial units address space ------------- 1941 & DeviceCOM::SCreateInitialUnitsPseudoAddressSpace, 1942 1943 // --- callback dispatcher utils (cont.) ------- 1944 & DeviceCOM::SAddCallbackDispatcherToRunLoopForMode, 1945 & DeviceCOM::SAddIsochCallbackDispatcherToRunLoopForMode, 1946 & DeviceCOM::SRemoveIsochCallbackDispatcherFromRunLoop, 1947 1948 // --- seize service --------------------------- 1949 & DeviceCOM::SSeize, 1950 1951 // --- more debugging -------------------------- 1952 & DeviceCOM::SFireLog, 1953 1954 // --- other methods --- new in v3 1955 & DeviceCOM::SGetBusCycleTime, 1956 1957 // 1958 // v4 1959 // 1960 & DeviceCOM::SCreateCompareSwapCommand64, 1961 & DeviceCOM::SCompareSwap64, 1962 & DeviceCOM::SGetBusGeneration, 1963 & DeviceCOM::SGetLocalNodeIDWithGeneration, 1964 & DeviceCOM::SGetRemoteNodeID, 1965 & DeviceCOM::SGetSpeedToNode, 1966 & DeviceCOM::SGetSpeedBetweenNodes, 1967 1968 // 1969 // v5/ 1970 // 1971 1972 & DeviceCOM::S_GetIRMNodeID 1973 1974 // 1975 // v6 1976 // 1977 1978 ,& DeviceCOM::S_ClipMaxRec2K 1979 ,& DeviceCOM::S_CreateNuDCLPool 1980 1981 // 1982 // v7 1983 // 1984 1985 , & DeviceCOM::S_GetSessionRef 1986 1987 // 1988 // v8 1989 // 1990 1991 , & DeviceCOM::S_CreateLocalIsochPortWithOptions 1992 1993 // 1994 // v9 1995 // 1996 1997 , &DeviceCOM::S_CreateVectorCommand 1998 1999 , &DeviceCOM::S_AllocateIRMBandwidthInGeneration 2000 2001 , &DeviceCOM::S_ReleaseIRMBandwidthInGeneration 2002 2003 , &DeviceCOM::S_AllocateIRMChannelInGeneration 2004 2005 , &DeviceCOM::S_ReleaseIRMChannelInGeneration 2006 2007 , &DeviceCOM::S_CreateIRMAllocation 2008 2009 , &DeviceCOM::S_CreateAsyncStreamListener 2010 2011 , &DeviceCOM::S_GetIsochAsyncPort 2012 2013 , &DeviceCOM::S_CreatePHYCommand 2014 2015 , &DeviceCOM::S_CreatePHYPacketListener 2016 2017 , &DeviceCOM::S_CreateAsyncStreamCommand 2018 2019 , &DeviceCOM::SGetCycleTimeAndUpTime 2020 } ; 2021 2022 DeviceCOM::DeviceCOM( CFDictionaryRef propertyTable, io_service_t service ) 2023 : Device( reinterpret_cast<const IUnknownVTbl &>( sInterface ), propertyTable, service ) 2024 { 2025 } 2026 2027 // ============================================================ 2028 // static allocator 2029 // ============================================================ 2030 2031 IOFireWireDeviceInterface** 2032 DeviceCOM::Alloc( CFDictionaryRef propertyTable, io_service_t service ) 2033 { 2034 DeviceCOM* me = nil ; 2035 2036 try { 2037 me = new DeviceCOM( propertyTable, service ) ; 2038 } catch ( ... ) { 2039 } 2040 2041 if( !me ) 2042 return nil ; 2043 2044 return reinterpret_cast<IOFireWireDeviceInterface**>(&me->GetInterface()) ; 2045 } 2046 2047 Boolean 2048 DeviceCOM::SInterfaceIsInited(IOFireWireLibDeviceRef self) 2049 { 2050 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->mIsInited; 2051 } 2052 2053 io_object_t 2054 DeviceCOM::SGetDevice(IOFireWireLibDeviceRef self) 2055 { 2056 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->mDefaultDevice; 2057 } 2058 2059 IOReturn 2060 DeviceCOM::SOpen(IOFireWireLibDeviceRef self) 2061 { 2062 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->Open() ; 2063 } 2064 2065 IOReturn 2066 DeviceCOM::SOpenWithSessionRef(IOFireWireLibDeviceRef self, IOFireWireSessionRef session) 2067 { 2068 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->OpenWithSessionRef(session) ; 2069 } 2070 2071 IOReturn 2072 DeviceCOM::SSeize( // v3+ 2073 IOFireWireLibDeviceRef self, 2074 IOOptionBits flags, 2075 ... ) 2076 { 2077 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->Seize( flags ) ; 2078 } 2079 2080 void 2081 DeviceCOM::SClose(IOFireWireLibDeviceRef self) 2082 { 2083 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->Close() ; 2084 } 2085 2086 // --- FireWire notification methods -------------- 2087 const Boolean 2088 DeviceCOM::SNotificationIsOn(IOFireWireLibDeviceRef self) 2089 { 2090 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->mNotifyIsOn; 2091 } 2092 2093 const IOReturn 2094 DeviceCOM::SAddCallbackDispatcherToRunLoop(IOFireWireLibDeviceRef self, CFRunLoopRef runLoop) 2095 { 2096 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AddCallbackDispatcherToRunLoop(runLoop) ; 2097 } 2098 2099 IOReturn 2100 DeviceCOM::SAddCallbackDispatcherToRunLoopForMode( // v3+ 2101 IOFireWireLibDeviceRef self, 2102 CFRunLoopRef runLoop, 2103 CFStringRef runLoopMode ) 2104 { 2105 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AddCallbackDispatcherToRunLoopForMode( runLoop, runLoopMode ) ; 2106 } 2107 2108 const void 2109 DeviceCOM::SRemoveCallbackDispatcherFromRunLoop(IOFireWireLibDeviceRef self) 2110 { 2111 DeviceCOM* me = IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis( self ) ; 2112 me->RemoveDispatcherFromRunLoop( me->mRunLoop, me->mRunLoopSource, me->mRunLoopMode ) ; 2113 2114 if ( me->mRunLoop ) 2115 { 2116 CFRelease( me->mRunLoop ) ; 2117 me->mRunLoop = 0 ; 2118 } 2119 2120 if ( me->mRunLoopSource ) 2121 { 2122 CFRelease( me->mRunLoopSource ) ; 2123 me->mRunLoopSource = 0 ; 2124 } 2125 2126 if ( me->mRunLoopMode ) 2127 { 2128 CFRelease( me->mRunLoopMode) ; 2129 me->mRunLoopMode = 0 ; 2130 } 2131 } 2132 2133 // Makes notification active. Returns false if notification could not be activated. 2134 const Boolean 2135 DeviceCOM::STurnOnNotification(IOFireWireLibDeviceRef self) 2136 { 2137 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->TurnOnNotification( self ) ; 2138 } 2139 2140 // Notification callbacks will no longer be called. 2141 void 2142 DeviceCOM::STurnOffNotification(IOFireWireLibDeviceRef self) 2143 { 2144 IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->TurnOffNotification() ; 2145 } 2146 2147 const IOFireWireBusResetHandler 2148 DeviceCOM::SSetBusResetHandler(IOFireWireLibDeviceRef self, IOFireWireBusResetHandler inBusResetHandler) 2149 { 2150 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->SetBusResetHandler(inBusResetHandler) ; 2151 } 2152 2153 const IOFireWireBusResetDoneHandler 2154 DeviceCOM::SSetBusResetDoneHandler(IOFireWireLibDeviceRef self, IOFireWireBusResetDoneHandler inBusResetDoneHandler) 2155 { 2156 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->SetBusResetDoneHandler(inBusResetDoneHandler) ; 2157 } 2158 2159 void 2160 DeviceCOM::SClientCommandIsComplete(IOFireWireLibDeviceRef self, FWClientCommandID commandID, IOReturn status) 2161 { 2162 IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->ClientCommandIsComplete(commandID, status); 2163 } 2164 2165 IOReturn 2166 DeviceCOM::SRead(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress * addr, void* buf, 2167 UInt32* size, Boolean failOnReset, UInt32 generation) 2168 { 2169 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->Read(device, *addr, buf, size, failOnReset, generation) ; 2170 } 2171 2172 IOReturn 2173 DeviceCOM::SReadQuadlet(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress * addr, 2174 UInt32* val, Boolean failOnReset, UInt32 generation) 2175 { 2176 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->ReadQuadlet(device, *addr, val, failOnReset, generation); 2177 } 2178 2179 IOReturn 2180 DeviceCOM::SWrite(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress * addr, const void* buf, UInt32* size, 2181 Boolean failOnReset, UInt32 generation) 2182 { 2183 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->Write(device, *addr, buf, size, failOnReset, generation) ; 2184 } 2185 2186 IOReturn 2187 DeviceCOM::SWriteQuadlet(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress* addr, const UInt32 val, 2188 Boolean failOnReset, UInt32 generation) 2189 { 2190 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->WriteQuadlet(device, *addr, val, failOnReset, generation) ; 2191 } 2192 2193 IOReturn 2194 DeviceCOM::SCompareSwap(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress* addr, UInt32 cmpVal, UInt32 newVal, Boolean failOnReset, UInt32 generation) 2195 { 2196 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CompareSwap(device, *addr, cmpVal, newVal, failOnReset, generation) ; 2197 } 2198 2199 // 2200 // v4 2201 // 2202 IOReturn 2203 DeviceCOM::SCompareSwap64( IOFireWireLibDeviceRef self, io_object_t device, const FWAddress* addr, 2204 UInt32* expectedVal, UInt32* newVal, UInt32* oldVal, IOByteCount size, Boolean failOnReset, 2205 UInt32 generation) 2206 { 2207 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CompareSwap64( device, *addr, expectedVal, 2208 newVal, oldVal, size, failOnReset, generation ) ; 2209 } 2210 2211 // 2212 // v4 2213 // 2214 IOFireWireLibCommandRef 2215 DeviceCOM::SCreateCompareSwapCommand64(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress* addr, UInt64 cmpVal, 2216 UInt64 newVal, IOFireWireLibCommandCallback callback, Boolean failOnReset, UInt32 generation, void* inRefCon, 2217 REFIID iid ) 2218 { 2219 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateCompareSwapCommand(device, 2220 addr ? *addr : FWAddress(), cmpVal, newVal, 2, callback, failOnReset, generation, inRefCon, iid) ; 2221 } 2222 2223 IOReturn 2224 DeviceCOM::SGetBusGeneration( IOFireWireLibDeviceRef self, UInt32* outGeneration ) 2225 { 2226 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetBusGeneration( outGeneration ) ; 2227 } 2228 2229 IOReturn 2230 DeviceCOM::SGetLocalNodeIDWithGeneration( IOFireWireLibDeviceRef self, UInt32 checkGeneration, UInt16* outLocalNodeID ) 2231 { 2232 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetLocalNodeIDWithGeneration( checkGeneration, outLocalNodeID ) ; 2233 } 2234 2235 IOReturn 2236 DeviceCOM::SGetRemoteNodeID( IOFireWireLibDeviceRef self, UInt32 checkGeneration, UInt16* outRemoteNodeID ) 2237 { 2238 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetRemoteNodeID( checkGeneration, outRemoteNodeID ) ; 2239 } 2240 2241 IOReturn 2242 DeviceCOM::SGetSpeedToNode( IOFireWireLibDeviceRef self, UInt32 checkGeneration, IOFWSpeed* outSpeed) 2243 { 2244 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetSpeedToNode( checkGeneration, outSpeed ) ; 2245 } 2246 2247 IOReturn 2248 DeviceCOM::SGetSpeedBetweenNodes( IOFireWireLibDeviceRef self, UInt32 checkGeneration, UInt16 srcNodeID, UInt16 destNodeID, IOFWSpeed* outSpeed) 2249 { 2250 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetSpeedBetweenNodes( checkGeneration, srcNodeID, destNodeID, outSpeed ) ; 2251 } 2252 2253#pragma mark - 2254 IOFireWireLibCommandRef 2255 DeviceCOM::SCreateReadCommand(IOFireWireLibDeviceRef self, 2256 io_object_t device, 2257 const FWAddress* addr, 2258 void* buf, 2259 UInt32 size, 2260 IOFireWireLibCommandCallback callback, 2261 Boolean failOnReset, 2262 UInt32 generation, 2263 void* inRefCon, 2264 REFIID iid) 2265 { 2266 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateReadCommand(device, addr ? *addr : FWAddress(), buf, size, callback, failOnReset, generation, inRefCon, iid) ; 2267 } 2268 2269 IOFireWireLibCommandRef 2270 DeviceCOM::SCreateReadQuadletCommand(IOFireWireLibDeviceRef self, io_object_t device, 2271 const FWAddress* addr, UInt32 val[], const UInt32 numQuads, IOFireWireLibCommandCallback callback, 2272 Boolean failOnReset, UInt32 generation, void* inRefCon, REFIID iid) 2273 { 2274 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateReadQuadletCommand(device, addr ? *addr : FWAddress(), val, numQuads, callback, failOnReset, generation, inRefCon, iid) ; 2275 } 2276 2277 IOFireWireLibCommandRef 2278 DeviceCOM::SCreateWriteCommand(IOFireWireLibDeviceRef self, io_object_t device, 2279 const FWAddress* addr, void* buf, UInt32 size, IOFireWireLibCommandCallback callback, 2280 Boolean failOnReset, UInt32 generation, void* inRefCon, REFIID iid) 2281 { 2282 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateWriteCommand( device, addr ? *addr : FWAddress(), buf, size, callback, failOnReset, generation, inRefCon, iid) ; 2283 } 2284 2285 IOFireWireLibCommandRef 2286 DeviceCOM::SCreateWriteQuadletCommand(IOFireWireLibDeviceRef self, io_object_t device, 2287 const FWAddress* addr, UInt32 quads[], const UInt32 numQuads, IOFireWireLibCommandCallback callback, 2288 Boolean failOnReset, UInt32 generation, void* inRefCon, REFIID iid) 2289 { 2290 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateWriteQuadletCommand(device, addr ? *addr : FWAddress(), quads, numQuads, callback, failOnReset, generation, inRefCon, iid) ; 2291 } 2292 2293 IOFireWireLibCommandRef 2294 DeviceCOM::SCreateCompareSwapCommand(IOFireWireLibDeviceRef self, io_object_t device, const FWAddress* addr, UInt32 cmpVal, UInt32 newVal, 2295 IOFireWireLibCommandCallback callback, Boolean failOnReset, UInt32 generation, void* inRefCon, REFIID iid) 2296 { 2297 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateCompareSwapCommand(device, 2298 addr ? *addr : FWAddress(), cmpVal, newVal, 1, callback, failOnReset, generation, inRefCon, iid) ; 2299 } 2300 2301 IOReturn 2302 DeviceCOM::SBusReset(IOFireWireLibDeviceRef self) 2303 { 2304 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->BusReset() ; 2305 } 2306 2307 2308#pragma mark - 2309 // 2310 // --- local unit directory support ------------------ 2311 // 2312 IOFireWireLibLocalUnitDirectoryRef 2313 DeviceCOM::SCreateLocalUnitDirectory(IOFireWireLibDeviceRef self, REFIID iid) 2314 { 2315 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateLocalUnitDirectory(iid); 2316 } 2317 2318 IOFireWireLibConfigDirectoryRef 2319 DeviceCOM::SGetConfigDirectory(IOFireWireLibDeviceRef self, REFIID iid) 2320 { 2321 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetConfigDirectory(iid) ; 2322 } 2323 2324 IOFireWireLibConfigDirectoryRef 2325 DeviceCOM::SCreateConfigDirectoryWithIOObject(IOFireWireLibDeviceRef self, io_object_t inObject, REFIID iid) 2326 { 2327 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateConfigDirectoryWithIOObject(inObject, iid) ; 2328 } 2329 2330#pragma mark - 2331 // 2332 // --- address space support ------------------ 2333 // 2334 IOFireWireLibPseudoAddressSpaceRef 2335 DeviceCOM::SCreatePseudoAddressSpace(IOFireWireLibDeviceRef self, UInt32 inLength, void* inRefCon, UInt32 inQueueBufferSize, 2336 void* inBackingStore, UInt32 inFlags, REFIID iid) 2337 { 2338 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreatePseudoAddressSpace(inLength, inRefCon, inQueueBufferSize, inBackingStore, inFlags, iid); 2339 } 2340 2341 IOFireWireLibPhysicalAddressSpaceRef 2342 DeviceCOM::SCreatePhysicalAddressSpace(IOFireWireLibDeviceRef self, UInt32 inLength, void* inBackingStore, UInt32 flags, REFIID iid) 2343 { 2344 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreatePhysicalAddressSpace(inLength, inBackingStore, flags, iid); 2345 } 2346 2347 IOFireWireLibPseudoAddressSpaceRef 2348 DeviceCOM::SCreateInitialUnitsPseudoAddressSpace( 2349 IOFireWireLibDeviceRef self, 2350 UInt32 inAddressLo, 2351 UInt32 inSize, 2352 void* inRefCon, 2353 UInt32 inQueueBufferSize, 2354 void* inBackingStore, 2355 UInt32 inFlags, 2356 REFIID iid) 2357 { 2358 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateInitialUnitsPseudoAddressSpace( inAddressLo, inSize, inRefCon, inQueueBufferSize, inBackingStore, inFlags, iid ) ; 2359 } 2360 2361 // 2362 // --- FireLog ----------------------------------- 2363 // 2364 IOReturn 2365 DeviceCOM::SFireLog( 2366 IOFireWireLibDeviceRef self, 2367 const char * format, 2368 ... ) 2369 { 2370 va_list ap ; 2371 va_start( ap, format ) ; 2372 2373 IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->FireLog( format, ap ) ; 2374 2375 va_end( ap ) ; 2376 2377 return kIOReturnSuccess ; 2378 } 2379 2380 // 2381 // --- isoch ----------------------------------- 2382 // 2383 IOReturn 2384 DeviceCOM::SAddIsochCallbackDispatcherToRunLoop( 2385 IOFireWireLibDeviceRef self, 2386 CFRunLoopRef runLoop) 2387 { 2388 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AddIsochCallbackDispatcherToRunLoopForMode( runLoop, kCFRunLoopCommonModes ) ; 2389 } 2390 2391 IOReturn 2392 DeviceCOM::SAddIsochCallbackDispatcherToRunLoopForMode( // v3+ 2393 IOFireWireLibDeviceRef self, 2394 CFRunLoopRef runLoop, 2395 CFStringRef runLoopMode ) 2396 { 2397 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AddIsochCallbackDispatcherToRunLoopForMode( runLoop, runLoopMode ) ; 2398 } 2399 2400 void 2401 DeviceCOM::SRemoveIsochCallbackDispatcherFromRunLoop( // v3+ 2402 IOFireWireLibDeviceRef self) 2403 { 2404 IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->RemoveIsochCallbackDispatcherFromRunLoop() ; 2405 } 2406 2407 IOFireWireLibRemoteIsochPortRef 2408 DeviceCOM::SCreateRemoteIsochPort( 2409 IOFireWireLibDeviceRef self, 2410 Boolean inTalking, 2411 REFIID iid) 2412 { 2413 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateRemoteIsochPort(inTalking, iid) ; 2414 } 2415 2416 IOFireWireLibLocalIsochPortRef 2417 DeviceCOM::S_CreateLocalIsochPort( 2418 IOFireWireLibDeviceRef self, 2419 Boolean talking, 2420 DCLCommand* dclProgram, 2421 UInt32 startEvent, 2422 UInt32 startState, 2423 UInt32 startMask, 2424 IOVirtualRange dclProgramRanges[], // optional optimization parameters 2425 UInt32 dclProgramRangeCount, 2426 IOVirtualRange bufferRanges[], 2427 UInt32 bufferRangeCount, 2428 REFIID iid) 2429 { 2430 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateLocalIsochPortWithOptions( talking, dclProgram, startEvent, startState, startMask, 2431 dclProgramRanges, dclProgramRangeCount, bufferRanges, 2432 bufferRangeCount, kFWIsochPortDefaultOptions, iid) ; 2433 } 2434 2435 IOFireWireLibIsochChannelRef 2436 DeviceCOM::SCreateIsochChannel( IOFireWireLibDeviceRef self, Boolean doIRM, UInt32 packetSize, 2437 IOFWSpeed prefSpeed, REFIID iid ) 2438 { 2439 IOFireWireLibIsochChannelRef result = 0 ; 2440 2441 IUnknownVTbl** iUnknown = reinterpret_cast<IUnknownVTbl**>(IsochChannelCOM::Alloc(*IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self), doIRM, packetSize, prefSpeed)) ; 2442 if (iUnknown) 2443 { 2444 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 2445 (*iUnknown)->Release(iUnknown) ; 2446 } 2447 2448 return result ; 2449 } 2450 2451 IOFireWireLibDCLCommandPoolRef 2452 DeviceCOM::SCreateDCLCommandPool( IOFireWireLibDeviceRef self, IOByteCount size, REFIID iid ) 2453 { 2454 IOFireWireLibDCLCommandPoolRef result = 0 ; 2455 2456 IUnknownVTbl** iUnknown = TraditionalDCLCommandPoolCOM::Alloc(*IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self), size ) ; 2457 if (iUnknown) 2458 { 2459 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 2460 (*iUnknown)->Release(iUnknown) ; 2461 } 2462 2463 return result ; 2464 } 2465 2466 void 2467 DeviceCOM::SPrintDCLProgram( IOFireWireLibDeviceRef self, const DCLCommand* dcl, UInt32 inDCLCount ) 2468 { 2469 const DCLCommand* currentDCL = dcl ; 2470 UInt32 index = 0 ; 2471 2472#ifdef __LP64__ 2473 printf( "IsochPort::printDCLProgram: dcl=%p, inDCLCount=%ud\n", dcl, inDCLCount) ; 2474#else 2475 printf( "IsochPort::printDCLProgram: dcl=%p, inDCLCount=%lud\n", dcl, inDCLCount) ; 2476#endif 2477 while ( (inDCLCount == 0 || index < inDCLCount ) && currentDCL ) 2478 { 2479#ifdef __LP64__ 2480 printf( "\n#0x%04X @%p next=%p, cmplrData=0x%08X, op=%u ", 2481 index, 2482 currentDCL, 2483 currentDCL->pNextDCLCommand, 2484 currentDCL->compilerData, 2485 currentDCL->opcode) ; 2486#else 2487 printf( "\n#0x%04lX @%p next=%p, cmplrData=0x%08lX, op=%lu ", 2488 index, 2489 currentDCL, 2490 currentDCL->pNextDCLCommand, 2491 currentDCL->compilerData, 2492 currentDCL->opcode) ; 2493#endif 2494 switch(currentDCL->opcode & ~kFWDCLOpFlagMask) 2495 { 2496 case kDCLSendPacketStartOp: 2497 //case kDCLSendPacketWithHeaderStartOp: 2498 case kDCLSendPacketOp: 2499 case kDCLReceivePacketStartOp: 2500 case kDCLReceivePacketOp: 2501#ifdef __LP64__ 2502 printf( "(DCLTransferPacket) buffer=%p, size=%u", 2503 ((DCLTransferPacket*)currentDCL)->buffer, 2504 ((DCLTransferPacket*)currentDCL)->size) ; 2505#else 2506 printf( "(DCLTransferPacket) buffer=%p, size=%lu", 2507 ((DCLTransferPacket*)currentDCL)->buffer, 2508 ((DCLTransferPacket*)currentDCL)->size) ; 2509#endif 2510 break ; 2511 2512 case kDCLSendBufferOp: 2513 case kDCLReceiveBufferOp: 2514#ifdef __LP64__ 2515 printf( "(DCLTransferBuffer) buffer=%p, size=%u, packetSize=0x%x, bufferOffset=%08X", 2516 ((DCLTransferBuffer*)currentDCL)->buffer, 2517 ((DCLTransferBuffer*)currentDCL)->size, 2518 ((DCLTransferBuffer*)currentDCL)->packetSize, 2519 ((DCLTransferBuffer*)currentDCL)->bufferOffset) ; 2520#else 2521 printf( "(DCLTransferBuffer) buffer=%p, size=%lu, packetSize=0x%x, bufferOffset=%08lX", 2522 ((DCLTransferBuffer*)currentDCL)->buffer, 2523 ((DCLTransferBuffer*)currentDCL)->size, 2524 ((DCLTransferBuffer*)currentDCL)->packetSize, 2525 ((DCLTransferBuffer*)currentDCL)->bufferOffset) ; 2526#endif 2527 break ; 2528 2529 case kDCLCallProcOp: 2530#ifdef __LP64__ 2531 printf( "(DCLCallProc) proc=%p, procData=%08llX", 2532 ((DCLCallProc*)currentDCL)->proc, 2533 (UInt64)((DCLCallProc*)currentDCL)->procData) ; 2534#else 2535 printf( "(DCLCallProc) proc=%p, procData=%08lX", 2536 ((DCLCallProc*)currentDCL)->proc, 2537 ((DCLCallProc*)currentDCL)->procData) ; 2538#endif 2539 break ; 2540 2541 case kDCLLabelOp: 2542 printf( "(DCLLabel)") ; 2543 break ; 2544 2545 case kDCLJumpOp: 2546 printf( "(DCLJump) pJumpDCLLabel=%p", 2547 ((DCLJump*)currentDCL)->pJumpDCLLabel) ; 2548 break ; 2549 2550 case kDCLSetTagSyncBitsOp: 2551 printf( "(DCLSetTagSyncBits) tagBits=%04x, syncBits=%04x", 2552 ((DCLSetTagSyncBits*)currentDCL)->tagBits, 2553 ((DCLSetTagSyncBits*)currentDCL)->syncBits) ; 2554 break ; 2555 2556 case kDCLUpdateDCLListOp: 2557#ifdef __LP64__ 2558 printf( "(DCLUpdateDCLList) dclCommandList=%p, numDCLCommands=%ud \n", 2559 ((DCLUpdateDCLList*)currentDCL)->dclCommandList, 2560 ((DCLUpdateDCLList*)currentDCL)->numDCLCommands) ; 2561#else 2562 printf( "(DCLUpdateDCLList) dclCommandList=%p, numDCLCommands=%lud \n", 2563 ((DCLUpdateDCLList*)currentDCL)->dclCommandList, 2564 ((DCLUpdateDCLList*)currentDCL)->numDCLCommands) ; 2565#endif 2566 for(UInt32 listIndex=0; listIndex < ((DCLUpdateDCLList*)currentDCL)->numDCLCommands; ++listIndex) 2567 { 2568 printf( "%p ", (((DCLUpdateDCLList*)currentDCL)->dclCommandList)[listIndex]) ; 2569 } 2570 2571 break ; 2572 2573 case kDCLPtrTimeStampOp: 2574 printf( "(DCLPtrTimeStamp) timeStampPtr=%p", 2575 ((DCLPtrTimeStamp*)currentDCL)->timeStampPtr) ; 2576 break ; 2577 2578 case kDCLSkipCycleOp: 2579 printf( "(DCLSkipCycle)") ; 2580 break ; 2581 2582 case kDCLNuDCLLeaderOp: 2583 printf( "(DCLNuDCLLeaderOp) DCL pool=%p", ((DCLNuDCLLeader*)currentDCL)->program ) ; 2584 break ; 2585 } 2586 2587 currentDCL = currentDCL->pNextDCLCommand ; 2588 ++index ; 2589 } 2590 2591 printf( "\n") ; 2592 2593 if ( inDCLCount > 0 && index != inDCLCount) 2594 printf( "unexpected end of program\n") ; 2595 2596 if ( inDCLCount > 0 && currentDCL != NULL) 2597 printf( "program too long for count\n") ; 2598 } 2599 2600 IOReturn 2601 DeviceCOM::S_GetIRMNodeID( IOFireWireLibDeviceRef self, UInt32 checkGeneration, UInt16* outIRMNodeID ) 2602 { 2603 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis( self )->GetIRMNodeID( checkGeneration, outIRMNodeID ) ; 2604 } 2605 2606 IOReturn 2607 DeviceCOM::S_ClipMaxRec2K( IOFireWireLibDeviceRef self, Boolean clipMaxRec ) 2608 { 2609 //fprintf(stderr, "DeviceCOM::S_ClipMaxRec2K\n") ; 2610 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->ClipMaxRec2K( clipMaxRec) ; 2611 } 2612 2613 IOFireWireLibNuDCLPoolRef 2614 DeviceCOM::S_CreateNuDCLPool( IOFireWireLibDeviceRef self, UInt32 capacity, REFIID iid ) 2615 { 2616 IOFireWireLibNuDCLPoolRef result = 0 ; 2617 2618 const IUnknownVTbl** iUnknown = NuDCLPoolCOM::Alloc( *IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis( self ), capacity ) ; 2619 if (iUnknown) 2620 { 2621 (*iUnknown)->QueryInterface(iUnknown, iid, (void**) & result) ; 2622 (*iUnknown)->Release(iUnknown) ; 2623 } 2624 2625 return result ; 2626 } 2627 2628 IOFireWireSessionRef 2629 DeviceCOM::S_GetSessionRef( IOFireWireLibDeviceRef self ) 2630 { 2631 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->GetSessionRef() ; 2632 } 2633 2634 IOFireWireLibLocalIsochPortRef 2635 DeviceCOM::S_CreateLocalIsochPortWithOptions( 2636 IOFireWireLibDeviceRef self, 2637 Boolean talking, 2638 DCLCommand* dclProgram, 2639 UInt32 startEvent, 2640 UInt32 startState, 2641 UInt32 startMask, 2642 IOVirtualRange dclProgramRanges[], // optional optimization parameters 2643 UInt32 dclProgramRangeCount, 2644 IOVirtualRange bufferRanges[], 2645 UInt32 bufferRangeCount, 2646 IOFWIsochPortOptions options, 2647 REFIID iid) 2648 { 2649 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateLocalIsochPortWithOptions( talking, dclProgram, startEvent, startState, startMask, 2650 dclProgramRanges, dclProgramRangeCount, bufferRanges, 2651 bufferRangeCount, options, iid) ; 2652 } 2653 2654 IOFireWireLibVectorCommandRef 2655 DeviceCOM::S_CreateVectorCommand( 2656 IOFireWireLibDeviceRef self, 2657 IOFireWireLibCommandCallback callback, 2658 void* inRefCon, 2659 REFIID iid) 2660 { 2661 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateVectorCommand( callback, inRefCon, iid ); 2662 } 2663 2664 IOFireWireLibCommandRef 2665 DeviceCOM::S_CreatePHYCommand( 2666 IOFireWireLibDeviceRef self, 2667 UInt32 data1, 2668 UInt32 data2, 2669 IOFireWireLibCommandCallback callback, 2670 Boolean failOnReset, 2671 UInt32 generation, 2672 void* inRefCon, 2673 REFIID iid ) 2674 { 2675 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreatePHYCommand( data1, data2, callback, failOnReset, generation, inRefCon, iid ); 2676 } 2677 2678 IOFireWireLibPHYPacketListenerRef 2679 DeviceCOM::S_CreatePHYPacketListener( 2680 IOFireWireLibDeviceRef self, 2681 UInt32 queueCount, 2682 REFIID iid) 2683 { 2684 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreatePHYPacketListener( queueCount, iid ); 2685 } 2686 2687 IOReturn DeviceCOM::S_AllocateIRMBandwidthInGeneration(IOFireWireLibDeviceRef self, UInt32 bandwidthUnits, UInt32 generation) 2688 { 2689 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AllocateIRMBandwidthInGeneration(bandwidthUnits, generation); 2690 } 2691 2692 IOReturn DeviceCOM::S_ReleaseIRMBandwidthInGeneration(IOFireWireLibDeviceRef self, UInt32 bandwidthUnits, UInt32 generation) 2693 { 2694 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->ReleaseIRMBandwidthInGeneration(bandwidthUnits, generation); 2695 } 2696 2697 IOReturn DeviceCOM::S_AllocateIRMChannelInGeneration(IOFireWireLibDeviceRef self, UInt8 isochChannel, UInt32 generation) 2698 { 2699 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->AllocateIRMChannelInGeneration(isochChannel, generation); 2700 } 2701 2702 IOReturn DeviceCOM::S_ReleaseIRMChannelInGeneration(IOFireWireLibDeviceRef self, UInt8 isochChannel, UInt32 generation) 2703 { 2704 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->ReleaseIRMChannelInGeneration(isochChannel, generation); 2705 } 2706 2707 IOFireWireLibIRMAllocationRef DeviceCOM::S_CreateIRMAllocation( IOFireWireLibDeviceRef self, 2708 Boolean releaseIRMResourcesOnFree, 2709 IOFireWireLibIRMAllocationLostNotificationProc callback, 2710 void *pLostNotificationProcRefCon, 2711 REFIID iid) 2712 { 2713 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateIRMAllocation(releaseIRMResourcesOnFree, 2714 callback, 2715 pLostNotificationProcRefCon, 2716 iid); 2717 } 2718 2719 IOFWAsyncStreamListenerInterfaceRef 2720 DeviceCOM::S_CreateAsyncStreamListener( 2721 IOFireWireLibDeviceRef self, 2722 UInt32 channel, 2723 IOFWAsyncStreamListenerHandler callback, 2724 void* inRefCon, 2725 UInt32 inQueueBufferSize, 2726 REFIID iid ) 2727 { 2728 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateAsyncStreamListener( channel, 2729 callback, 2730 inRefCon, 2731 inQueueBufferSize, 2732 iid ); 2733 } 2734 2735 mach_port_t DeviceCOM::S_GetIsochAsyncPort( IOFireWireLibDeviceRef self ) 2736 { 2737 IOReturn status = kIOReturnSuccess; 2738 mach_port_t port = NULL; 2739 2740 Device * device = IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self); 2741 2742 if( !device->IsochAsyncPortsExist() ) 2743 { 2744 status = device->CreateIsochAsyncPorts(); 2745 } 2746 2747 if( status == kIOReturnSuccess ) 2748 { 2749 port = device->GetIsochAsyncPort(); 2750 } 2751 2752 return port; 2753 } 2754 2755 IOFireWireLibCommandRef DeviceCOM::S_CreateAsyncStreamCommand( IOFireWireLibDeviceRef self, 2756 UInt32 channel, 2757 UInt32 sync, 2758 UInt32 tag, 2759 void* buf, 2760 UInt32 size, 2761 IOFireWireLibCommandCallback callback, 2762 Boolean failOnReset, 2763 UInt32 generation, 2764 void* inRefCon, 2765 REFIID iid) 2766 { 2767 return IOFireWireIUnknown::InterfaceMap<DeviceCOM>::GetThis(self)->CreateAsyncStreamCommand( channel, 2768 sync, 2769 tag, 2770 buf, 2771 size, 2772 callback, 2773 failOnReset, 2774 generation, 2775 inRefCon, 2776 iid ); 2777 } 2778 2779} // namespace 2780