1/* 2 * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22/* 23 * IOFireWireLibIsochPort.cpp 24 * IOFireWireFamily 25 * 26 * Created on Mon Mar 12 2001. 27 * Copyright (c) 2001-2002 Apple Computer, Inc. All rights reserved. 28 * 29 * $Log: IOFireWireLibIsochPort.cpp,v $ 30 * Revision 1.58 2009/01/16 02:53:19 collin 31 * and finally put TOT back... 32 * 33 * Revision 1.54 2009/01/15 01:40:02 collin 34 * <rdar://problem/6400981> BRB-VERIFY: 10A222: Trying to record a movie through QT X, getting error message. 35 * 36 * Revision 1.53 2008/05/06 00:14:48 collin 37 * more k64 changes 38 * 39 * Revision 1.52 2007/03/14 01:01:14 collin 40 * *** empty log message *** 41 * 42 * Revision 1.51 2007/02/15 19:42:08 ayanowit 43 * For 4369537, eliminated support for legacy DCL SendPacketWithHeader, since it didn't work anyway, and NuDCL does support it. 44 * 45 * Revision 1.50 2007/02/15 17:18:54 ayanowit 46 * Fixed a panic found with ProIO DCL program in FCP. Related to recent changes for 64-bit app support. 47 * 48 * Revision 1.49 2007/02/07 06:35:22 collin 49 * *** empty log message *** 50 * 51 * Revision 1.48 2007/01/26 20:52:31 ayanowit 52 * changes to user-space isoch stuff to support 64-bit apps. 53 * 54 * Revision 1.47 2007/01/11 04:28:05 collin 55 * *** empty log message *** 56 * 57 * Revision 1.46 2007/01/08 18:47:20 ayanowit 58 * More 64-bit changes for isoch. 59 * 60 * Revision 1.45 2007/01/02 18:14:12 ayanowit 61 * Enabled building the plug-in lib 4-way FAT. Also, fixed compile problems for 64-bit. 62 * 63 * Revision 1.44 2006/12/21 21:17:46 ayanowit 64 * More changes necessary to eventually get support for 64-bit apps working (4222965). 65 * 66 * Revision 1.43 2006/12/16 00:07:48 ayanowit 67 * fixed some of the leopard user-lib changes. was failing on ppc systems. 68 * 69 * Revision 1.42 2006/12/13 21:34:24 ayanowit 70 * For 4222965, replaced all io async method calls with new Leopard API version. 71 * 72 * Revision 1.41 2006/12/13 01:11:23 ayanowit 73 * For 4222969, replaced the remaining calls to IOConnectMethod... struct variants. 74 * 75 * Revision 1.40 2006/12/12 22:39:05 ayanowit 76 * For radar 4222965, changed all scalar in, scalar out calls to IOConnectMethod... to use new Leopard IOConnectCall... API. 77 * 78 * Revision 1.39 2006/08/21 22:41:11 collin 79 * *** empty log message *** 80 * 81 * Revision 1.38 2006/02/09 00:21:55 niels 82 * merge chardonnay branch to tot 83 * 84 * Revision 1.37 2005/04/02 02:43:46 niels 85 * exporter works outside IOFireWireFamily 86 * 87 * Revision 1.36.4.6 2006/01/31 04:49:57 collin 88 * *** empty log message *** 89 * 90 * Revision 1.36.4.4 2006/01/17 00:35:00 niels 91 * <rdar://problem/4399365> FireWire NuDCL APIs need Rosetta support 92 * 93 * Revision 1.36.4.3 2006/01/04 00:45:54 collin 94 * *** empty log message *** 95 * 96 * Revision 1.36.4.2 2005/08/06 01:31:31 collin 97 * *** empty log message *** 98 * 99 * Revision 1.36.4.1 2005/07/23 00:30:46 collin 100 * *** empty log message *** 101 * 102 * Revision 1.36 2005/03/12 03:27:52 collin 103 * *** empty log message *** 104 * 105 * Revision 1.35 2005/02/18 03:19:05 niels 106 * fix isight 107 * 108 * Revision 1.34 2004/05/04 22:52:20 niels 109 * *** empty log message *** 110 * 111 * Revision 1.33 2004/02/17 23:13:23 niels 112 * *** empty log message *** 113 * 114 * Revision 1.32 2004/02/17 23:12:27 niels 115 * *** empty log message *** 116 * 117 * Revision 1.31 2004/02/17 20:23:58 niels 118 * keep track if local isoch port has started or not to avoid leaking when stop is called on an unstarted port 119 * 120 * Revision 1.30 2003/12/19 22:07:46 niels 121 * send force stop when channel dies/system sleeps 122 * 123 * Revision 1.29 2003/08/25 08:39:17 niels 124 * *** empty log message *** 125 * 126 * Revision 1.28 2003/08/20 23:33:37 niels 127 * *** empty log message *** 128 * 129 * Revision 1.27 2003/08/20 18:48:45 niels 130 * *** empty log message *** 131 * 132 * Revision 1.26 2003/08/18 23:18:15 niels 133 * *** empty log message *** 134 * 135 * Revision 1.25 2003/08/14 17:47:33 niels 136 * *** empty log message *** 137 * 138 * Revision 1.24 2003/07/29 22:49:25 niels 139 * *** empty log message *** 140 * 141 * Revision 1.23 2003/07/24 20:49:50 collin 142 * *** empty log message *** 143 * 144 * Revision 1.22 2003/07/24 06:30:59 collin 145 * *** empty log message *** 146 * 147 * Revision 1.21 2003/07/21 06:53:10 niels 148 * merge isoch to TOT 149 * 150 * Revision 1.20.6.6 2003/07/21 06:44:48 niels 151 * *** empty log message *** 152 * 153 * Revision 1.20.6.5 2003/07/18 00:17:47 niels 154 * *** empty log message *** 155 * 156 * Revision 1.20.6.4 2003/07/10 00:11:58 niels 157 * *** empty log message *** 158 * 159 * Revision 1.20.6.3 2003/07/09 21:24:07 niels 160 * *** empty log message *** 161 * 162 * Revision 1.20.6.2 2003/07/03 22:10:26 niels 163 * fix iidc/dv rcv 164 * 165 * Revision 1.20.6.1 2003/07/01 20:54:24 niels 166 * isoch merge 167 * 168 */ 169 170#import "IOFireWireLibIsochPort.h" 171#import "IOFireWireLibDevice.h" 172#import "IOFireWireLibNuDCLPool.h" 173#import "IOFireWireLibNuDCL.h" 174#import "IOFireWireLibCoalesceTree.h" 175 176#import <IOKit/iokitmig.h> 177#import <mach/mach.h> 178#import <System/libkern/OSCrossEndian.h> 179 180#define IOFIREWIREISOCHPORTIMP_INTERFACE \ 181 & IsochPortCOM::SGetSupported, \ 182 & IsochPortCOM::SAllocatePort, \ 183 & IsochPortCOM::SReleasePort, \ 184 & IsochPortCOM::SStart, \ 185 & IsochPortCOM::SStop, \ 186 & IsochPortCOM::SSetRefCon, \ 187 & IsochPortCOM::SGetRefCon 188 189namespace IOFireWireLib { 190 RemoteIsochPort::Interface RemoteIsochPortCOM::sInterface = 191 { 192 INTERFACEIMP_INTERFACE, 193 1, 0, 194 195 IOFIREWIREISOCHPORTIMP_INTERFACE, 196 & RemoteIsochPortCOM::SSetGetSupportedHandler, 197 & RemoteIsochPortCOM::SSetAllocatePortHandler, 198 & RemoteIsochPortCOM::SSetReleasePortHandler, 199 & RemoteIsochPortCOM::SSetStartHandler, 200 & RemoteIsochPortCOM::SSetStopHandler, 201 } ; 202 203 // ============================================================ 204 // utility functions 205 // ============================================================ 206 207 Boolean 208 GetDCLDataBuffer( 209 DCLCommand* dcl, 210 IOVirtualAddress* outDataBuffer, 211 IOByteCount* outDataLength) 212 { 213 Boolean result = false ; 214 215 switch(dcl->opcode & ~kFWDCLOpFlagMask) 216 { 217 case kDCLSendPacketStartOp: 218 //case kDCLSendPacketWithHeaderStartOp: 219 case kDCLSendPacketOp: 220 case kDCLReceivePacketStartOp: 221 case kDCLReceivePacketOp: 222 *outDataBuffer = (IOVirtualAddress)((DCLTransferPacket*)dcl)->buffer ; 223 *outDataLength = ((DCLTransferPacket*)dcl)->size ; 224 result = true ; 225 break ; 226 227 case kDCLSendBufferOp: 228 case kDCLReceiveBufferOp: 229 //zzz what should I do here? 230 break ; 231 232 case kDCLPtrTimeStampOp: 233 *outDataBuffer = (IOVirtualAddress)((DCLPtrTimeStamp*)dcl)->timeStampPtr ; 234 *outDataLength = sizeof( *( ((DCLPtrTimeStamp*)dcl)->timeStampPtr) ) ; 235 result = true ; 236 break ; 237 238 default: 239 break ; 240 } 241 242 return result ; 243 } 244 245 IOByteCount 246 GetDCLSize( 247 DCLCommand* dcl) 248 { 249 IOByteCount result = 0 ; 250 251 switch(dcl->opcode & ~kFWDCLOpFlagMask) 252 { 253 case kDCLSendPacketStartOp: 254 //case kDCLSendPacketWithHeaderStartOp: 255 case kDCLSendPacketOp: 256 case kDCLReceivePacketStartOp: 257 case kDCLReceivePacketOp: 258 result = sizeof(UserExportDCLTransferPacket) ; 259 break ; 260 261 case kDCLSendBufferOp: 262 case kDCLReceiveBufferOp: 263 result = sizeof(UserExportDCLTransferBuffer) ; 264 break ; 265 266 case kDCLCallProcOp: 267 result = sizeof(UserExportDCLCallProc) ; 268 break ; 269 270 case kDCLLabelOp: 271 result = sizeof(UserExportDCLLabel) ; 272 break ; 273 274 case kDCLJumpOp: 275 result = sizeof(UserExportDCLJump) ; 276 break ; 277 278 case kDCLSetTagSyncBitsOp: 279 result = sizeof(UserExportDCLSetTagSyncBits) ; 280 break ; 281 282 case kDCLUpdateDCLListOp: 283 result = sizeof(UserExportDCLUpdateDCLList) ; 284 break ; 285 286 case kDCLPtrTimeStampOp: 287 result = sizeof(UserExportDCLPtrTimeStamp) ; 288 break; 289 290 case kDCLSkipCycleOp: 291 result = sizeof(UserExportDCLCommand) ; 292 break; 293 } 294 295 return result ; 296 } 297 298#pragma mark - 299 // ============================================================ 300 // 301 // IsochPort 302 // 303 // ============================================================ 304 305 IsochPort::IsochPort( const IUnknownVTbl & interface, Device & device, bool talking, bool allocateKernPort ) 306 : IOFireWireIUnknown( interface ), 307 mDevice( device ), 308 mKernPortRef( 0 ), 309 mTalking( talking ) 310 { 311 mDevice.AddRef() ; 312 } 313 314 IsochPort::~IsochPort() 315 { 316 if ( mKernPortRef ) 317 { 318 IOReturn error = kIOReturnSuccess; 319 320 uint32_t outputCnt = 0; 321 const uint64_t inputs[1]={(const uint64_t)mKernPortRef}; 322 error = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 323 kReleaseUserObject, 324 inputs,1,NULL,&outputCnt); 325 326 DebugLogCond( error, "Couldn't release kernel port" ) ; 327 } 328 329 mDevice.Release() ; 330 } 331 332 IOReturn 333 IsochPort::GetSupported( 334 IOFWSpeed& maxSpeed, 335 UInt64& chanSupported ) 336 { 337 uint32_t outputCnt = 3; 338 uint64_t outputVal[3]; 339 const uint64_t inputs[1]={(const uint64_t)mKernPortRef}; 340 IOReturn result = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 341 kIsochPort_GetSupported, 342 inputs,1, 343 outputVal,&outputCnt); 344 maxSpeed = (IOFWSpeed)(outputVal[0] & 0xFFFFFFFF); 345 chanSupported = ((outputVal[1] & 0xFFFFFFFF)<<32)+(outputVal[2] & 0xFFFFFFFF); 346 return result; 347 } 348 349 IOReturn 350 IsochPort::AllocatePort( IOFWSpeed speed, UInt32 chan ) 351 { 352 uint32_t outputCnt = 0; 353 const uint64_t inputs[2] = {speed, chan}; 354 return IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 355 mDevice.MakeSelectorWithObject( kIsochPort_AllocatePort_d, mKernPortRef ), 356 inputs,2, 357 NULL,&outputCnt); 358 } 359 360 IOReturn 361 IsochPort::ReleasePort() 362 { 363 uint32_t outputCnt = 0; 364 return IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 365 mDevice.MakeSelectorWithObject( kIsochPort_ReleasePort_d, mKernPortRef ), 366 NULL,0, 367 NULL,&outputCnt); 368 } 369 370 IOReturn 371 IsochPort::Start() 372 { 373 uint32_t outputCnt = 0; 374 return IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 375 mDevice.MakeSelectorWithObject( kIsochPort_Start_d, mKernPortRef ), 376 NULL,0, 377 NULL,&outputCnt); 378 } 379 380 IOReturn 381 IsochPort::Stop() 382 { 383 uint32_t outputCnt = 0; 384 return IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 385 mDevice.MakeSelectorWithObject( kIsochPort_Stop_d, mKernPortRef ), 386 NULL,0, 387 NULL,&outputCnt); 388 } 389 390#pragma mark - 391 // ============================================================ 392 // 393 // IsochPortCOM 394 // 395 // ============================================================ 396 397 IsochPortCOM::IsochPortCOM( const IUnknownVTbl & interface, Device& userclient, bool talking, bool allocateKernPort ) 398 : IsochPort( interface, userclient, talking, allocateKernPort ) 399 { 400 } 401 402 IsochPortCOM::~IsochPortCOM() 403 { 404 } 405 406 IOReturn 407 IsochPortCOM::SGetSupported( 408 IOFireWireLibIsochPortRef self, 409 IOFWSpeed* maxSpeed, 410 UInt64* chanSupported ) 411 { 412 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->GetSupported(*maxSpeed, *chanSupported) ; 413 } 414 415 IOReturn 416 IsochPortCOM::SAllocatePort( 417 IOFireWireLibIsochPortRef self, 418 IOFWSpeed speed, 419 UInt32 chan ) 420 { 421 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->AllocatePort(speed, chan) ; 422 } 423 424 IOReturn 425 IsochPortCOM::SReleasePort( 426 IOFireWireLibIsochPortRef self) 427 { 428 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->ReleasePort() ; 429 } 430 431 IOReturn 432 IsochPortCOM::SStart( 433 IOFireWireLibIsochPortRef self) 434 { 435 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->Start() ; 436 } 437 438 IOReturn 439 IsochPortCOM::SStop( 440 IOFireWireLibIsochPortRef self) 441 { 442 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->Stop() ; 443 } 444 445 void 446 IsochPortCOM::SSetRefCon( 447 IOFireWireLibIsochPortRef self, 448 void* inRefCon) 449 { 450 IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->SetRefCon(inRefCon) ; 451 } 452 453 void* 454 IsochPortCOM::SGetRefCon( 455 IOFireWireLibIsochPortRef self) 456 { 457 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->GetRefCon() ; 458 } 459 460 Boolean 461 IsochPortCOM::SGetTalking( 462 IOFireWireLibIsochPortRef self) 463 { 464 return IOFireWireIUnknown::InterfaceMap<IsochPortCOM>::GetThis(self)->GetTalking() ; 465 } 466 467#pragma mark - 468 // ============================================================ 469 // 470 // RemoteIsochPort 471 // 472 // ============================================================ 473 474 RemoteIsochPort::RemoteIsochPort( const IUnknownVTbl & interface, Device& userclient, bool talking ) 475 : IsochPortCOM( interface, userclient, talking ), 476 mGetSupportedHandler(0), 477 mAllocatePortHandler(0), 478 mReleasePortHandler(0), 479 mStartHandler(0), 480 mStopHandler(0), 481 mRefInterface( reinterpret_cast<IOFireWireIsochPortInterface**>(& GetInterface()) ) 482 { 483 } 484 485 IOReturn 486 RemoteIsochPort::GetSupported( 487 IOFWSpeed& maxSpeed, 488 UInt64& chanSupported) 489 { 490 if (mGetSupportedHandler) 491 return (*mGetSupportedHandler)(mRefInterface, & maxSpeed, & chanSupported) ; 492 else 493 return kIOReturnUnsupported ; // should we return unsupported if user proc doesn't answer? 494 } 495 496 IOReturn 497 RemoteIsochPort::AllocatePort( 498 IOFWSpeed speed, 499 UInt32 chan ) 500 { 501 if (mAllocatePortHandler) 502 return (*mAllocatePortHandler)(mRefInterface, speed, chan) ; 503 else 504 return kIOReturnSuccess ; 505 } 506 507 IOReturn 508 RemoteIsochPort::ReleasePort() 509 { 510 if (mReleasePortHandler) 511 return (*mReleasePortHandler)(mRefInterface) ; 512 else 513 return kIOReturnSuccess ; 514 } 515 516 IOReturn 517 RemoteIsochPort::Start() 518 { 519 if (mStartHandler) 520 return (*mStartHandler)(mRefInterface) ; 521 else 522 return kIOReturnSuccess ; 523 } 524 525 IOReturn 526 RemoteIsochPort::Stop() 527 { 528 if (mStopHandler) 529 return (*mStopHandler)(mRefInterface) ; 530 else 531 return kIOReturnSuccess ; 532 } 533 534 535 IOFireWireLibIsochPortGetSupportedCallback 536 RemoteIsochPort::SetGetSupportedHandler( 537 IOFireWireLibIsochPortGetSupportedCallback inHandler) 538 { 539 IOFireWireLibIsochPortGetSupportedCallback oldHandler = mGetSupportedHandler ; 540 mGetSupportedHandler = inHandler ; 541 542 return oldHandler ; 543 } 544 545 IOFireWireLibIsochPortAllocateCallback 546 RemoteIsochPort::SetAllocatePortHandler( 547 IOFireWireLibIsochPortAllocateCallback inHandler) 548 { 549 IOFireWireLibIsochPortAllocateCallback oldHandler = mAllocatePortHandler ; 550 mAllocatePortHandler = inHandler ; 551 552 return oldHandler ; 553 } 554 555 IOFireWireLibIsochPortCallback 556 RemoteIsochPort::SetReleasePortHandler( 557 IOFireWireLibIsochPortCallback inHandler) 558 { 559 IOFireWireLibIsochPortCallback oldHandler = mReleasePortHandler ; 560 mReleasePortHandler = inHandler ; 561 562 return oldHandler ; 563 } 564 565 IOFireWireLibIsochPortCallback 566 RemoteIsochPort::SetStartHandler( 567 IOFireWireLibIsochPortCallback inHandler) 568 { 569 IOFireWireLibIsochPortCallback oldHandler = mStartHandler ; 570 mStartHandler = inHandler ; 571 572 return oldHandler ; 573 } 574 575 IOFireWireLibIsochPortCallback 576 RemoteIsochPort::SetStopHandler( 577 IOFireWireLibIsochPortCallback inHandler) 578 { 579 IOFireWireLibIsochPortCallback oldHandler = mStopHandler ; 580 mStopHandler = inHandler ; 581 582 return oldHandler ; 583 } 584 585#pragma mark - 586 // ============================================================ 587 // 588 // RemoteIsochPortCOM 589 // 590 // ============================================================ 591 RemoteIsochPortCOM::RemoteIsochPortCOM( Device& userclient, bool talking ) 592 : RemoteIsochPort( reinterpret_cast<const IUnknownVTbl &>( sInterface ), userclient, talking ) 593 { 594 } 595 596 RemoteIsochPortCOM::~RemoteIsochPortCOM() 597 { 598 } 599 600 IUnknownVTbl** 601 RemoteIsochPortCOM::Alloc( Device& userclient, bool talking ) 602 { 603 RemoteIsochPortCOM* me = nil ; 604 605 try { 606 me = new RemoteIsochPortCOM( userclient, talking ) ; 607 } catch(...) { 608 } 609 610 return (nil==me) ? nil : reinterpret_cast<IUnknownVTbl**>(& me->GetInterface()) ; 611 } 612 613 614 HRESULT 615 RemoteIsochPortCOM::QueryInterface(REFIID iid, void ** ppv ) 616 { 617 HRESULT result = S_OK ; 618 *ppv = nil ; 619 620 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; 621 622 if ( CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWireRemoteIsochPortInterfaceID) ) 623 { 624 *ppv = & GetInterface() ; 625 AddRef() ; 626 } 627 else 628 { 629 *ppv = nil ; 630 result = E_NOINTERFACE ; 631 } 632 633 CFRelease(interfaceID) ; 634 return result ; 635 } 636 637 IOFireWireLibIsochPortGetSupportedCallback 638 RemoteIsochPortCOM::SSetGetSupportedHandler( 639 PortRef self, 640 IOFireWireLibIsochPortGetSupportedCallback inHandler) 641 { 642 return IOFireWireIUnknown::InterfaceMap<RemoteIsochPortCOM>::GetThis(self)->SetGetSupportedHandler(inHandler) ; 643 } 644 645 IOFireWireLibIsochPortAllocateCallback 646 RemoteIsochPortCOM::SSetAllocatePortHandler( 647 PortRef self, 648 IOFireWireLibIsochPortAllocateCallback inHandler) 649 { 650 return IOFireWireIUnknown::InterfaceMap<RemoteIsochPortCOM>::GetThis(self)->SetAllocatePortHandler(inHandler) ; 651 } 652 653 IOFireWireLibIsochPortCallback 654 RemoteIsochPortCOM::SSetReleasePortHandler( 655 PortRef self, 656 IOFireWireLibIsochPortCallback inHandler) 657 { 658 return IOFireWireIUnknown::InterfaceMap<RemoteIsochPortCOM>::GetThis(self)->SetReleasePortHandler(inHandler) ; 659 } 660 661 IOFireWireLibIsochPortCallback 662 RemoteIsochPortCOM::SSetStartHandler( 663 PortRef self, 664 IOFireWireLibIsochPortCallback inHandler) 665 { 666 return IOFireWireIUnknown::InterfaceMap<RemoteIsochPortCOM>::GetThis(self)->SetStartHandler(inHandler) ; 667 } 668 669 IOFireWireLibIsochPortCallback 670 RemoteIsochPortCOM::SSetStopHandler( 671 PortRef self, 672 IOFireWireLibIsochPortCallback inHandler) 673 { 674 return IOFireWireIUnknown::InterfaceMap<RemoteIsochPortCOM>::GetThis(self)->SetStopHandler(inHandler) ; 675 } 676 677#pragma mark - 678 LocalIsochPortCOM::Interface LocalIsochPortCOM::sInterface = 679 { 680 INTERFACEIMP_INTERFACE 681 ,4,0 682 683 ,IOFIREWIREISOCHPORTIMP_INTERFACE 684 ,& LocalIsochPortCOM::SModifyJumpDCL 685 ,& LocalIsochPortCOM::SPrintDCLProgram 686 ,& LocalIsochPortCOM::SModifyTransferPacketDCLSize 687 ,& LocalIsochPortCOM::SModifyTransferPacketDCLBuffer 688 ,& LocalIsochPortCOM::SModifyTransferPacketDCL 689 ,& LocalIsochPortCOM::S_SetFinalizeCallback 690 , & LocalIsochPortCOM::S_SetResourceUsageFlags 691 , & LocalIsochPortCOM::S_Notify 692 } ; 693 694 LocalIsochPort::LocalIsochPort( const IUnknownVTbl & interface, Device & userclient, bool talking, 695 DCLCommand* program, UInt32 startEvent, UInt32 startState, UInt32 startMask, 696 IOVirtualRange userProgramRanges[], UInt32 userProgramRangeCount, 697 IOVirtualRange userBufferRanges[], UInt32 userBufferRangeCount, IOFWIsochPortOptions options ) 698 : IsochPortCOM( interface, userclient, talking, false ) 699 , mDCLProgram( program ) 700 , mExpectedStopTokens(0) 701 , mDeferredReleaseCount(0) 702 , mFinalizeCallback(nil) 703 , mBufferRanges( nil ) 704 , mBufferAddressRanges( nil ) 705 , mStarted( false ) 706 { 707 // sorry about the spaghetti.. hope you're hungry: 708 709 if ( !program ) 710 { 711 DebugLog( "no DCL program!\n" ) ; 712 throw kIOReturnBadArgument ; 713 } 714 715// DeviceCOM::SPrintDCLProgram ( nil, program, 0 ) ; 716 717 IOReturn error = kIOReturnSuccess ; 718 719 // trees used to coalesce program/data ranges 720 CoalesceTree bufferTree ; 721 722 // check if user passed in any virtual memory ranges to start with... 723 if ( userBufferRanges ) 724 { 725 for( unsigned index=0; index < userBufferRangeCount; ++index ) 726 bufferTree.CoalesceRange( userBufferRanges[index]) ; 727 } 728 729 IOByteCount programExportBytes = 0 ; 730 IOVirtualAddress programData = 0 ; 731 732 LocalIsochPortAllocateParams params ; 733 { 734 params.programExportBytes = 0 ; 735 params.programData = 0 ; 736 } 737 738 if ( program->opcode == kDCLNuDCLLeaderOp ) 739 { 740 if( !error ) 741 { 742 NuDCLPool* pool = reinterpret_cast<NuDCLPool*>( reinterpret_cast< DCLNuDCLLeader* >( program )->program ) ; 743 744 params.version = kDCLExportDataNuDCLRosettaVersion ; // new-style DCL program 745 746 pool->CoalesceBuffers( bufferTree ) ; 747 748 mBufferRangeCount = bufferTree.GetCount() ; 749 mBufferRanges = new IOVirtualRange[ mBufferRangeCount ] ; 750 if ( !mBufferRanges ) 751 { 752 error = kIOReturnNoMemory ; 753 } 754 else 755 { 756 bufferTree.GetCoalesceList( mBufferRanges ) ; 757 758 mBufferAddressRanges = new FWVirtualAddressRange[ mBufferRangeCount ] ; 759 if ( !mBufferAddressRanges ) 760 { 761 error = kIOReturnNoMemory ; 762 } 763 else 764 for (unsigned int i=0;i<mBufferRangeCount;i++) 765 { 766 mBufferAddressRanges[i].address = mBufferRanges[i].address; 767 mBufferAddressRanges[i].length = mBufferRanges[i].length; 768 } 769 770 programExportBytes = pool->Export( &programData, mBufferRanges, mBufferRangeCount ) ; 771 params.programExportBytes = programExportBytes ; 772 params.programData = programData; 773 } 774 } 775 } 776 else 777 { 778 unsigned programCount = 0 ; 779 780 params.version = kDCLExportDataLegacyVersion ; // old-style DCL program 781 782 // count DCLs in program and coalesce buffers: 783 for( DCLCommand * dcl = mDCLProgram; dcl != nil; dcl = dcl->pNextDCLCommand ) 784 { 785 IOVirtualRange tempRange ; 786 if ( GetDCLDataBuffer ( dcl, & tempRange.address, & tempRange.length ) ) 787 { 788 bufferTree.CoalesceRange ( tempRange ) ; 789 } 790 791 ++programCount ; 792 } 793 794 InfoLog("program count is %d\n", programCount) ; 795 796 if ( !error ) 797 { 798 error = ExportDCLs( &programData, &programExportBytes ) ; 799 params.programData = programData; 800 params.programExportBytes = programExportBytes; 801 } 802 803 if ( !error ) 804 { 805 mBufferRangeCount = bufferTree.GetCount() ; 806 mBufferRanges = new IOVirtualRange[ mBufferRangeCount ] ; 807 808 if ( !mBufferRanges ) 809 { 810 error = kIOReturnNoMemory ; 811 } 812 else 813 { 814 bufferTree.GetCoalesceList( mBufferRanges ) ; 815 816 mBufferAddressRanges = new FWVirtualAddressRange[ mBufferRangeCount ] ; 817 if ( !mBufferAddressRanges ) 818 { 819 error = kIOReturnNoMemory ; 820 } 821 else 822 for (unsigned int i=0;i<mBufferRangeCount;i++) 823 { 824 mBufferAddressRanges[i].address = mBufferRanges[i].address; 825 mBufferAddressRanges[i].length = mBufferRanges[i].length; 826 } 827 } 828 } 829 } 830 831 if ( error ) 832 { 833 throw error ; 834 } 835 836// // allocate lists to store buffer ranges 837// // and get coalesced buffer lists 838// 839// UInt32 bufferRangeCount = bufferTree.GetCount() ; 840// IOVirtualRange bufferRanges[ bufferRangeCount ] ; 841// 842// bufferTree.GetCoalesceList ( bufferRanges ) ; 843 844 // fill out param struct and submit to kernel 845 params.bufferRanges = (mach_vm_address_t)mBufferAddressRanges ; 846 params.bufferRangeCount = mBufferRangeCount ; 847 params.talking = mTalking ; 848 params.startEvent = startEvent ; 849 params.startState = startState ; 850 params.startMask = startMask ; 851 params.userObj = (mach_vm_address_t) this ; 852 params.options = options ; 853 854#if 0 855 params.options |= kFWIsochEnableRobustness; 856#endif 857 858 InfoLog("startEvent=%x, startState=%x, startMask=%x\n", params.startEvent, params.startState, params.startMask) ; 859 860#ifndef __LP64__ 861 ROSETTA_ONLY( 862 { 863 params.version = OSSwapInt32( params.version ); 864 params.talking = params.talking; // byte 865 params.startEvent = OSSwapInt32( params.startEvent ); 866 params.startState = OSSwapInt32( params.startState ); 867 params.startMask = OSSwapInt32( params.startMask ); 868 params.programExportBytes = OSSwapInt32( params.programExportBytes ); 869 params.programData = OSSwapInt64( params.programData ); 870 871 for( UInt32 i = 0; i < params.bufferRangeCount; i++ ) 872 { 873 IOAddressRange *pAddressRange = (IOAddressRange*) (params.bufferRanges+(i*sizeof(IOAddressRange))); 874 875 pAddressRange->address = OSSwapInt64( pAddressRange->address ); 876 pAddressRange->length = OSSwapInt64( pAddressRange->length ); 877 878 } 879 880 params.bufferRangeCount = OSSwapInt32( params.bufferRangeCount ); 881 params.bufferRanges = OSSwapInt64(params.bufferRanges ); 882 params.options = (IOFWIsochPortOptions)OSSwapInt32( params.options | kFWIsochBigEndianUpdates ); 883 params.userObj = (mach_vm_address_t)OSSwapInt64((mach_vm_address_t)params.userObj ); 884 } 885 ); 886#endif 887 888 uint32_t outputCnt = 0; 889 size_t outputStructSize = sizeof( UserObjectHandle ) ; 890 error = IOConnectCallMethod(mDevice.GetUserClientConnection(), 891 kLocalIsochPort_Allocate, 892 NULL,0, 893 & params,sizeof (params), 894 NULL,&outputCnt, 895 &mKernPortRef,&outputStructSize); 896#ifndef __LP64__ 897 ROSETTA_ONLY( 898 { 899 mKernPortRef = (UserObjectHandle)OSSwapInt32( (UInt32)mKernPortRef ); 900 } 901 ); 902#endif 903 904 if (error) 905 { 906 DebugLog ( "Couldn't create local isoch port (error=%x)\nCheck your buffers!\n", error ) ; 907 DebugLog ( "Found buffers:\n" ) ; 908 909#if IOFIREWIRELIBDEBUG 910 for( unsigned index=0; index < mBufferRangeCount; ++index ) 911 { 912#ifdef __LP64__ 913 DebugLog ( "\%u: <0x%x>-<0x%x>\n", index, (unsigned)mBufferRanges[index].address, 914 (unsigned)mBufferRanges[index].address + mBufferRanges[index].length ) ; 915#else 916 DebugLog ( "\%u: <0x%x>-<0x%lx>\n", index, (unsigned)mBufferRanges[index].address, 917 (unsigned)mBufferRanges[index].address + mBufferRanges[index].length ) ; 918#endif 919 } 920#endif 921 922 throw error ; 923 } 924 925 { 926 uint64_t refrncData[kOSAsyncRef64Count]; 927 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) & LocalIsochPort::s_DCLStopTokenCallProcHandler; 928 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long)this; 929 uint32_t outputCnt = 0; 930 const uint64_t inputs[1]={(const uint64_t)mKernPortRef}; 931 932 error = IOConnectCallAsyncScalarMethod(mDevice.GetUserClientConnection(), 933 kSetAsyncRef_DCLCallProc, 934 mDevice.GetIsochAsyncPort(), 935 refrncData,kOSAsyncRef64Count, 936 inputs,1, 937 NULL,&outputCnt); 938 939 if( error ) 940 { 941 throw error ; 942 } 943 } 944 945 if ( params.programData ) 946 { 947 vm_deallocate( mach_task_self (), (vm_address_t) programData, programExportBytes ) ; // this is temporary storage 948 } 949 950 // make our mutex 951 pthread_mutex_init ( & mMutex, nil ) ; 952 } 953 954 LocalIsochPort::~LocalIsochPort () 955 { 956 delete[] mBufferRanges ; 957 delete[] mBufferAddressRanges; 958 959 pthread_mutex_destroy( & mMutex ) ; 960 } 961 962 ULONG 963 LocalIsochPort::Release () 964 { 965 Lock () ; 966 967 if ( mExpectedStopTokens > 0 ) 968 { 969 Unlock () ; 970 ++ mDeferredReleaseCount ; 971 return mRefCount ; 972 } 973 974 Unlock () ; 975 976// while( true ) 977// { 978// Lock() ; 979// bool run = ( mExpectedStopTokens > 0 ) ; 980// Unlock() ; 981// 982// if ( !run ) 983// { 984// break ; 985// } 986// 987// ::CFRunLoopRunInMode( kCFRunLoopDefaultMode, 1, true ) ; 988// } 989 990 return IsochPortCOM::Release() ; 991 } 992 993 IOReturn 994 LocalIsochPort::Start() 995 { 996 IOReturn error = IsochPort::Start() ; 997 if ( !error ) 998 { 999 Lock() ; 1000 mStarted = true ; 1001 Unlock() ; 1002 } 1003 1004 return error ; 1005 } 1006 1007 IOReturn 1008 LocalIsochPort::Stop () 1009 { 1010 Lock() ; 1011 if ( mStarted ) 1012 { 1013 mStarted = false ; 1014 ++mExpectedStopTokens ; 1015 InfoLog("waiting for %lu stop tokens\n", mExpectedStopTokens) ; 1016 } 1017 Unlock() ; 1018 1019 return IsochPortCOM::Stop() ; // call superclass Stop() 1020 } 1021 1022 IOReturn 1023 LocalIsochPort::ModifyJumpDCL ( DCLJump* inJump, DCLLabel* inLabel ) 1024 { 1025 inJump->pJumpDCLLabel = inLabel ; 1026 1027 uint32_t outputCnt = 0; 1028 const uint64_t inputs[2] = {inJump->compilerData, inLabel->compilerData}; 1029 IOReturn result = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 1030 mDevice.MakeSelectorWithObject( kLocalIsochPort_ModifyJumpDCL_d, mKernPortRef ), 1031 inputs,2, 1032 NULL,&outputCnt); 1033 return result ; 1034 } 1035 1036 IOReturn 1037 LocalIsochPort::ModifyTransferPacketDCLSize ( DCLTransferPacket* dcl, IOByteCount newSize ) 1038 { 1039 //kLocalIsochPort_ModifyTransferPacketDCLSize, 1040 return kIOReturnUnsupported ; 1041 } 1042 1043 void 1044 LocalIsochPort::s_DCLStopTokenCallProcHandler ( void * self, IOReturn e ) 1045 { 1046 ((LocalIsochPort*)self)->DCLStopTokenCallProcHandler(e) ; 1047 } 1048 1049 void 1050 LocalIsochPort::DCLStopTokenCallProcHandler( IOReturn ) 1051 { 1052 if ( mExpectedStopTokens > 0 ) 1053 { 1054 Lock() ; 1055 mExpectedStopTokens-- ; 1056 Unlock() ; 1057 1058 if ( mExpectedStopTokens == 0 ) 1059 { 1060 if ( mFinalizeCallback ) 1061 (*mFinalizeCallback)(mRefCon) ; 1062 1063 // use a local so we don't touch "this" after release 1064 UInt32 release_count = mDeferredReleaseCount; 1065 while ( release_count > 0 ) 1066 { 1067 --release_count ; 1068 Release() ; 1069 } 1070 } 1071 } 1072 } 1073#if 0 1074 void 1075 LocalIsochPort::S_DCLKernelCallout( DCLCallProc * dcl ) 1076 { 1077 (*dcl->proc)(dcl->procData) ; 1078 1079 uint32_t outputCnt = 0; 1080 const uint64_t inputs[1]={(const uint64_t)dcl->compilerData}; 1081 1082 IOReturn result = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 1083 Device::MakeSelectorWithObject( kLocalIsochPort_RunDCLUpdateList_d, port->mKernPortRef ), 1084 inputs,1, 1085 NULL,&outputCnt); 1086 } 1087 1088 void 1089 LocalIsochPort::S_NuDCLKernelCallout ( NuDCL * dcl ) 1090 { 1091 (*dcl->fData.callback)(dcl->fData.refcon, (NuDCLRef)dcl) ; 1092 1093 uint32_t outputCnt = 0; 1094 const uint64_t inputs[1]={(const uint64_t)dcl->fExportIndex}; 1095 1096 IOReturn result = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 1097 Device::MakeSelectorWithObject( kLocalIsochPort_RunNuDCLUpdateList_d, mKernPortRef ), 1098 inputs,1, 1099 NULL,&outputCnt); 1100 } 1101#endif 1102 1103 IOReturn 1104 LocalIsochPort::SetResourceUsageFlags ( 1105 IOFWIsochResourceFlags flags ) 1106 { 1107 uint32_t outputCnt = 0; 1108 const uint64_t inputs[1]={(const uint64_t)flags}; 1109 1110 return IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 1111 mDevice.MakeSelectorWithObject( kIsochPort_SetIsochResourceFlags_d, mKernPortRef ), 1112 inputs,1, 1113 NULL,&outputCnt); 1114 } 1115 1116 IOReturn 1117 LocalIsochPort::ExportDCLs( IOVirtualAddress * exportBuffer, IOByteCount * exportBytes ) 1118 { 1119 IOReturn error = kIOReturnSuccess ; 1120 1121 // see how much space we need for serialization... 1122 1123// unsigned byteCount = 0 ; 1124 *exportBytes = 0 ; 1125 for( DCLCommand * dcl = mDCLProgram; dcl != NULL; dcl = dcl->pNextDCLCommand ) 1126 { 1127 *exportBytes += GetDCLSize( dcl ) ; 1128 1129 switch ( dcl->opcode & ~kFWDCLOpFlagMask ) 1130 { 1131 case kDCLUpdateDCLListOp : 1132 { 1133 // update DCLs store a copy of their update list in the export buffer 1134 *exportBytes += sizeof( mach_vm_address_t ) * ((DCLUpdateDCLList*)dcl)->numDCLCommands ; 1135 break ; 1136 } 1137 case kDCLCallProcOp : 1138 { 1139 *exportBytes += sizeof( uint64_t[kOSAsyncRef64Count]) ; 1140 break ; 1141 } 1142 } 1143 } 1144 1145 // buffer to hold copy of DCLs in program 1146 error = vm_allocate( mach_task_self (), (vm_address_t*)exportBuffer, *exportBytes, true /*anywhere*/ ) ; 1147 1148 if ( !*exportBuffer && !error ) 1149 { 1150 error = kIOReturnNoMemory ; 1151 } 1152 1153 // start from beginning 1154 { 1155 unsigned offset = 0 ; 1156 IOVirtualAddress buffer = *exportBuffer ; 1157 1158 InfoLog("exporting DCLs, pass 1...\n") ; 1159 1160 for( DCLCommand * dcl = mDCLProgram; dcl != NULL ; dcl = dcl->pNextDCLCommand ) 1161 { 1162 1163 unsigned size = GetDCLSize( dcl ) ; 1164 1165 dcl->compilerData = offset ; // save for later. 1166 1167 // Copy the DCLs into the buffer using the ExportDCL structs 1168 switch(dcl->opcode & ~kFWDCLOpFlagMask) 1169 { 1170 case kDCLSendPacketStartOp: 1171 //case kDCLSendPacketWithHeaderStartOp: 1172 case kDCLSendPacketOp: 1173 case kDCLReceivePacketStartOp: 1174 case kDCLReceivePacketOp: 1175 { 1176 UserExportDCLTransferPacket *pUserExportDCLTransferPacket = (UserExportDCLTransferPacket*) buffer; 1177 pUserExportDCLTransferPacket->pClientDCLStruct = (mach_vm_address_t) dcl; 1178 pUserExportDCLTransferPacket->pNextDCLCommand = (mach_vm_address_t) ((DCLTransferPacket*)dcl)->pNextDCLCommand; 1179 pUserExportDCLTransferPacket->compilerData = ((DCLTransferPacket*)dcl)->compilerData; 1180 pUserExportDCLTransferPacket->opcode = ((DCLTransferPacket*)dcl)->opcode; 1181 pUserExportDCLTransferPacket->buffer = (mach_vm_address_t) ((DCLTransferPacket*)dcl)->buffer; 1182 pUserExportDCLTransferPacket->size = ((DCLTransferPacket*)dcl)->size; 1183 } 1184 break ; 1185 1186 case kDCLSendBufferOp: 1187 case kDCLReceiveBufferOp: 1188 { 1189 UserExportDCLTransferBuffer *pUserExportDCLTransferBuffer = (UserExportDCLTransferBuffer*) buffer; 1190 pUserExportDCLTransferBuffer->pClientDCLStruct = (mach_vm_address_t) dcl; 1191 pUserExportDCLTransferBuffer->pNextDCLCommand = (mach_vm_address_t) ((DCLTransferBuffer*)dcl)->pNextDCLCommand; 1192 pUserExportDCLTransferBuffer->compilerData = ((DCLTransferBuffer*)dcl)->compilerData; 1193 pUserExportDCLTransferBuffer->opcode = ((DCLTransferBuffer*)dcl)->opcode; 1194 pUserExportDCLTransferBuffer->buffer = (mach_vm_address_t) ((DCLTransferBuffer*)dcl)->buffer; 1195 pUserExportDCLTransferBuffer->size = ((DCLTransferBuffer*)dcl)->size; 1196 pUserExportDCLTransferBuffer->packetSize = ((DCLTransferBuffer*)dcl)->packetSize; 1197 pUserExportDCLTransferBuffer->reserved = ((DCLTransferBuffer*)dcl)->reserved; 1198 pUserExportDCLTransferBuffer->bufferOffset = ((DCLTransferBuffer*)dcl)->bufferOffset; 1199 } 1200 break ; 1201 1202 case kDCLCallProcOp: 1203 { 1204 UserExportDCLCallProc *pUserExportDCLCallProc = (UserExportDCLCallProc*) buffer; 1205 pUserExportDCLCallProc->pClientDCLStruct = (mach_vm_address_t) dcl; 1206 pUserExportDCLCallProc->pNextDCLCommand = (mach_vm_address_t) ((DCLCallProc*)dcl)->pNextDCLCommand; 1207 pUserExportDCLCallProc->compilerData = ((DCLCallProc*)dcl)->compilerData; 1208 pUserExportDCLCallProc->opcode = ((DCLCallProc*)dcl)->opcode; 1209 pUserExportDCLCallProc->proc = (mach_vm_address_t) ((DCLCallProc*)dcl)->proc; 1210 //pUserExportDCLCallProc->procData = (uint64_t) ((DCLCallProc*)dcl)->procData; 1211 pUserExportDCLCallProc->procData = (uint64_t)dcl ; 1212 size += sizeof( uint64_t[kOSAsyncRef64Count]) ; 1213 } 1214 break ; 1215 1216 case kDCLLabelOp: 1217 { 1218 UserExportDCLLabel *pUserExportDCLLabel = (UserExportDCLLabel*) buffer; 1219 pUserExportDCLLabel->pClientDCLStruct = (mach_vm_address_t) dcl; 1220 pUserExportDCLLabel->pNextDCLCommand = (mach_vm_address_t) ((DCLLabel*)dcl)->pNextDCLCommand; 1221 pUserExportDCLLabel->compilerData = ((DCLLabel*)dcl)->compilerData; 1222 pUserExportDCLLabel->opcode = ((DCLLabel*)dcl)->opcode; 1223 } 1224 break ; 1225 1226 case kDCLJumpOp: 1227 { 1228 UserExportDCLJump *pUserExportDCLJump = (UserExportDCLJump*) buffer; 1229 pUserExportDCLJump->pClientDCLStruct = (mach_vm_address_t) dcl; 1230 pUserExportDCLJump->pNextDCLCommand = (mach_vm_address_t) ((DCLJump*)dcl)->pNextDCLCommand; 1231 pUserExportDCLJump->compilerData = ((DCLJump*)dcl)->compilerData; 1232 pUserExportDCLJump->opcode = ((DCLJump*)dcl)->opcode; 1233 pUserExportDCLJump->pJumpDCLLabel = (mach_vm_address_t) ((DCLJump*)dcl)->pJumpDCLLabel; 1234 } 1235 break ; 1236 1237 case kDCLSetTagSyncBitsOp: 1238 { 1239 UserExportDCLSetTagSyncBits *pUserExportDCLSetTagSyncBits = (UserExportDCLSetTagSyncBits*) buffer; 1240 pUserExportDCLSetTagSyncBits->pClientDCLStruct = (mach_vm_address_t) dcl; 1241 pUserExportDCLSetTagSyncBits->pNextDCLCommand = (mach_vm_address_t) ((DCLSetTagSyncBits*)dcl)->pNextDCLCommand; 1242 pUserExportDCLSetTagSyncBits->compilerData = ((DCLSetTagSyncBits*)dcl)->compilerData; 1243 pUserExportDCLSetTagSyncBits->opcode = ((DCLSetTagSyncBits*)dcl)->opcode; 1244 pUserExportDCLSetTagSyncBits->tagBits = ((DCLSetTagSyncBits*)dcl)->tagBits; 1245 pUserExportDCLSetTagSyncBits->syncBits = ((DCLSetTagSyncBits*)dcl)->syncBits; 1246 } 1247 break ; 1248 1249 case kDCLUpdateDCLListOp: 1250 { 1251 UserExportDCLUpdateDCLList *pUserExportDCLUpdateDCLList = (UserExportDCLUpdateDCLList*) buffer; 1252 pUserExportDCLUpdateDCLList->pClientDCLStruct = (mach_vm_address_t) dcl; 1253 pUserExportDCLUpdateDCLList->pNextDCLCommand = (mach_vm_address_t) ((DCLUpdateDCLList*)dcl)->pNextDCLCommand; 1254 pUserExportDCLUpdateDCLList->compilerData = ((DCLUpdateDCLList*)dcl)->compilerData; 1255 pUserExportDCLUpdateDCLList->opcode = ((DCLUpdateDCLList*)dcl)->opcode; 1256 pUserExportDCLUpdateDCLList->dclCommandList = (mach_vm_address_t) ((DCLUpdateDCLList*)dcl)->dclCommandList; 1257 pUserExportDCLUpdateDCLList->numDCLCommands = ((DCLUpdateDCLList*)dcl)->numDCLCommands; 1258 size += ( sizeof( mach_vm_address_t ) * ((DCLUpdateDCLList*)dcl)->numDCLCommands ) ; 1259 } 1260 break ; 1261 1262 case kDCLPtrTimeStampOp: 1263 { 1264 UserExportDCLPtrTimeStamp *pUserExportDCLPtrTimeStamp = (UserExportDCLPtrTimeStamp*) buffer; 1265 pUserExportDCLPtrTimeStamp->pClientDCLStruct = (mach_vm_address_t) dcl; 1266 pUserExportDCLPtrTimeStamp->pNextDCLCommand = (mach_vm_address_t) ((DCLPtrTimeStamp*)dcl)->pNextDCLCommand; 1267 pUserExportDCLPtrTimeStamp->compilerData = ((DCLPtrTimeStamp*)dcl)->compilerData; 1268 pUserExportDCLPtrTimeStamp->opcode = ((DCLPtrTimeStamp*)dcl)->opcode; 1269 pUserExportDCLPtrTimeStamp->timeStampPtr = (mach_vm_address_t) ((DCLPtrTimeStamp*)dcl)->timeStampPtr; 1270 } 1271 break ; 1272 1273 case kDCLSkipCycleOp: 1274 { 1275 UserExportDCLCommand *pUserExportDCLCommand = (UserExportDCLCommand*) buffer; 1276 pUserExportDCLCommand->pClientDCLStruct = (mach_vm_address_t) dcl; 1277 pUserExportDCLCommand->pNextDCLCommand = (mach_vm_address_t) ((DCLCommand*)dcl)->pNextDCLCommand; 1278 pUserExportDCLCommand->compilerData = ((DCLCommand*)dcl)->compilerData; 1279 pUserExportDCLCommand->opcode = ((DCLCommand*)dcl)->opcode; 1280 pUserExportDCLCommand->operands[0] = ((DCLCommand*)dcl)->operands[0]; 1281 } 1282 break ; 1283 } 1284 1285 // Account for this DCL's exported bytes 1286 buffer += size ; 1287 offset += size ; 1288 } 1289 1290 InfoLog("...done\n") ; 1291 } 1292 1293 // some DCLs (jumps and update list DCLs) refer to other DCLs with 1294 // user space pointers which makes translation a bit harder. 1295 // The 'compilerData' field of all the DCLs in our export data block 1296 // contain an offset in bytes from the beginning of the exported data 1297 // block.. 1298 // We now replace any user space pointers with offsets for kernel use.. 1299 { 1300 unsigned offset = 0 ; 1301 1302 InfoLog("exporting DCLs, pass 2... export size=%d bytes\n", (int)*exportBytes ) ; 1303 1304 while( offset < *exportBytes ) 1305 { 1306 UserExportDCLCommand * dcl = (UserExportDCLCommand*)(*exportBuffer + offset ) ; 1307 DCLCommand *pClientDCL = (DCLCommand *) dcl->pClientDCLStruct; 1308 1309// DebugLog("DCL=%p, offset=%x, opcode=%x\n", dcl, offset, dcl->opcode) ; 1310 1311 { 1312 unsigned opcode = dcl->opcode & ~kFWDCLOpFlagMask ; 1313 assert( opcode <= 15 || opcode == 20 ) ; 1314 } 1315 1316 unsigned size = GetDCLSize( pClientDCL ) ; 1317 1318 switch ( dcl->opcode & ~kFWDCLOpFlagMask ) 1319 { 1320 case kDCLUpdateDCLListOp : 1321 { 1322 // make list of offsets from list of user space DCL pointers 1323 // List starts after DCL in question on export buffer 1324 mach_vm_address_t* list = (mach_vm_address_t*)( ((UserExportDCLUpdateDCLList*)dcl) + 1 ) ; 1325 for( unsigned index=0; index < ((UserExportDCLUpdateDCLList*)dcl)->numDCLCommands; ++index ) 1326 { 1327 list[ index ] = (mach_vm_address_t) ((DCLUpdateDCLList*)pClientDCL)->dclCommandList[ index ]->compilerData ; 1328 } 1329 1330 size += sizeof( mach_vm_address_t ) * ((DCLUpdateDCLList*)pClientDCL)->numDCLCommands ; 1331 1332 break ; 1333 } 1334 1335 case kDCLJumpOp : 1336 { 1337 ((UserExportDCLJump*)dcl)->pJumpDCLLabel = (mach_vm_address_t) ((DCLJump*)pClientDCL)->pJumpDCLLabel->compilerData ; 1338 break ; 1339 } 1340 1341 case kDCLCallProcOp : 1342 { 1343 size += sizeof( uint64_t[kOSAsyncRef64Count]) ; 1344 break ; 1345 } 1346 1347 default : 1348 1349 break ; 1350 } 1351 1352#ifndef __LP64__ 1353 ROSETTA_ONLY( 1354 { 1355 switch(dcl->opcode & ~kFWDCLOpFlagMask) 1356 { 1357 case kDCLSendPacketStartOp: 1358 //case kDCLSendPacketWithHeaderStartOp: 1359 case kDCLSendPacketOp: 1360 case kDCLReceivePacketStartOp: 1361 case kDCLReceivePacketOp: 1362 ((UserExportDCLTransferPacket*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLTransferPacket*)dcl)->pNextDCLCommand ); 1363 ((UserExportDCLTransferPacket*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLTransferPacket*)dcl)->compilerData ); 1364 ((UserExportDCLTransferPacket*)dcl)->opcode = OSSwapInt32( ((UserExportDCLTransferPacket*)dcl)->opcode ); 1365 ((UserExportDCLTransferPacket*)dcl)->buffer = (mach_vm_address_t)OSSwapInt64( ((UserExportDCLTransferPacket*)dcl)->buffer ); 1366 ((UserExportDCLTransferPacket*)dcl)->size = OSSwapInt32( ((UserExportDCLTransferPacket*)dcl)->size ); 1367 break ; 1368 1369 case kDCLSendBufferOp: 1370 case kDCLReceiveBufferOp: 1371 ((UserExportDCLTransferBuffer*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLTransferBuffer*)dcl)->pNextDCLCommand ); 1372 ((UserExportDCLTransferBuffer*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLTransferBuffer*)dcl)->compilerData ); 1373 ((UserExportDCLTransferBuffer*)dcl)->opcode = OSSwapInt32( ((UserExportDCLTransferBuffer*)dcl)->opcode ); 1374 ((UserExportDCLTransferBuffer*)dcl)->buffer = (mach_vm_address_t)OSSwapInt64(((UserExportDCLTransferBuffer*)dcl)->buffer ); 1375 ((UserExportDCLTransferBuffer*)dcl)->size = OSSwapInt32( ((UserExportDCLTransferBuffer*)dcl)->size ); 1376 ((UserExportDCLTransferBuffer*)dcl)->packetSize = OSSwapInt16( ((UserExportDCLTransferBuffer*)dcl)->packetSize ); 1377 ((UserExportDCLTransferBuffer*)dcl)->reserved = OSSwapInt16( ((UserExportDCLTransferBuffer*)dcl)->reserved ); 1378 ((UserExportDCLTransferBuffer*)dcl)->bufferOffset = OSSwapInt32( ((UserExportDCLTransferBuffer*)dcl)->bufferOffset ); 1379 break ; 1380 1381 case kDCLCallProcOp: 1382 ((UserExportDCLCallProc*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLCallProc*)dcl)->pNextDCLCommand ); 1383 ((UserExportDCLCallProc*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLCallProc*)dcl)->compilerData ); 1384 ((UserExportDCLCallProc*)dcl)->opcode = OSSwapInt32( ((UserExportDCLCallProc*)dcl)->opcode ); 1385 ((UserExportDCLCallProc*)dcl)->proc = (mach_vm_address_t)OSSwapInt64(((UserExportDCLCallProc*)dcl)->proc ); 1386 ((UserExportDCLCallProc*)dcl)->procData = OSSwapInt64( ((UserExportDCLCallProc*)dcl)->procData ); 1387 break ; 1388 1389 case kDCLLabelOp: 1390 ((UserExportDCLLabel*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLLabel*)dcl)->pNextDCLCommand ); 1391 ((UserExportDCLLabel*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLLabel*)dcl)->compilerData ); 1392 ((UserExportDCLLabel*)dcl)->opcode = OSSwapInt32( ((UserExportDCLLabel*)dcl)->opcode ); 1393 break ; 1394 1395 case kDCLJumpOp: 1396 ((UserExportDCLJump*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64( ((UserExportDCLJump*)dcl)->pNextDCLCommand ); 1397 ((UserExportDCLJump*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLJump*)dcl)->compilerData ); 1398 ((UserExportDCLJump*)dcl)->opcode = OSSwapInt32( ((UserExportDCLJump*)dcl)->opcode ); 1399 ((UserExportDCLJump*)dcl)->pJumpDCLLabel = (mach_vm_address_t)OSSwapInt64(((UserExportDCLJump*)dcl)->pJumpDCLLabel ); 1400 break ; 1401 1402 case kDCLSetTagSyncBitsOp: 1403 ((UserExportDCLSetTagSyncBits*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLSetTagSyncBits*)dcl)->pNextDCLCommand ); 1404 ((UserExportDCLSetTagSyncBits*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLSetTagSyncBits*)dcl)->compilerData ); 1405 ((UserExportDCLSetTagSyncBits*)dcl)->opcode = OSSwapInt32( ((UserExportDCLSetTagSyncBits*)dcl)->opcode ); 1406 ((UserExportDCLSetTagSyncBits*)dcl)->tagBits = OSSwapInt16( ((UserExportDCLSetTagSyncBits*)dcl)->tagBits ); 1407 ((UserExportDCLSetTagSyncBits*)dcl)->syncBits = OSSwapInt16( ((UserExportDCLSetTagSyncBits*)dcl)->syncBits ); 1408 break ; 1409 1410 case kDCLUpdateDCLListOp: 1411 ((UserExportDCLUpdateDCLList*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLUpdateDCLList*)dcl)->pNextDCLCommand ); 1412 ((UserExportDCLUpdateDCLList*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLUpdateDCLList*)dcl)->compilerData ); 1413 ((UserExportDCLUpdateDCLList*)dcl)->opcode = OSSwapInt32( ((UserExportDCLUpdateDCLList*)dcl)->opcode ); 1414 1415 { 1416 mach_vm_address_t * list = (mach_vm_address_t *)( ((UserExportDCLUpdateDCLList*)dcl) + 1 ) ; 1417 for( unsigned index=0; index < ((UserExportDCLUpdateDCLList*)dcl)->numDCLCommands; ++index ) 1418 { 1419 list[ index ] = (mach_vm_address_t)OSSwapInt64(list[ index ] ); 1420 } 1421 } 1422 1423 ((UserExportDCLUpdateDCLList*)dcl)->dclCommandList = (mach_vm_address_t)OSSwapInt64(((UserExportDCLUpdateDCLList*)dcl)->dclCommandList ); 1424 ((UserExportDCLUpdateDCLList*)dcl)->numDCLCommands = OSSwapInt32( ((UserExportDCLUpdateDCLList*)dcl)->numDCLCommands ); 1425 break ; 1426 1427 case kDCLPtrTimeStampOp: 1428 ((UserExportDCLPtrTimeStamp*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLPtrTimeStamp*)dcl)->pNextDCLCommand ); 1429 ((UserExportDCLPtrTimeStamp*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLPtrTimeStamp*)dcl)->compilerData ); 1430 ((UserExportDCLPtrTimeStamp*)dcl)->opcode = OSSwapInt32( ((UserExportDCLPtrTimeStamp*)dcl)->opcode ); 1431 ((UserExportDCLPtrTimeStamp*)dcl)->timeStampPtr = (mach_vm_address_t)OSSwapInt64(((UserExportDCLPtrTimeStamp*)dcl)->timeStampPtr ); 1432 break; 1433 1434 case kDCLSkipCycleOp: 1435 ((UserExportDCLCommand*)dcl)->pNextDCLCommand = (mach_vm_address_t)OSSwapInt64(((UserExportDCLCommand*)dcl)->pNextDCLCommand ); 1436 ((UserExportDCLCommand*)dcl)->compilerData = OSSwapInt32( ((UserExportDCLCommand*)dcl)->compilerData ); 1437 ((UserExportDCLCommand*)dcl)->opcode = OSSwapInt32( ((UserExportDCLCommand*)dcl)->opcode ); 1438 ((UserExportDCLCommand*)dcl)->operands[0] = OSSwapInt32( ((UserExportDCLCommand*)dcl)->operands[0] ); 1439 break; 1440 } 1441 } 1442 ); 1443#endif 1444 1445 offset += size ; 1446 1447 } 1448 1449 InfoLog("...done\n") ; 1450 1451 } 1452 1453 // fill in DCL compiler data fields with ( program index + 1 ) ; 1454 { 1455 unsigned count = 0 ; 1456 for( DCLCommand * dcl = mDCLProgram; dcl != nil; dcl = dcl->pNextDCLCommand ) 1457 { 1458 dcl->compilerData = ++count ; // index incremented here.. 1459 // compiler data for DCL should be index + 1 1460 } 1461 } 1462 1463 return error ; 1464 } 1465 1466 IOReturn 1467 LocalIsochPort::Notify ( 1468 IOFWDCLNotificationType notificationType, 1469 void ** inDCLList, 1470 UInt32 numDCLs ) 1471 { 1472 IOReturn error = kIOReturnSuccess ; 1473 1474 switch( notificationType ) 1475 { 1476 case kFWNuDCLModifyNotification: 1477 { 1478 IOByteCount dataSize = 0 ; 1479 for( unsigned index=0; index < numDCLs; ++index ) 1480 { 1481 dataSize += 4 + ((NuDCL**)inDCLList)[ index ]->Export( NULL, NULL, 0 ) ; 1482 } 1483 1484 UInt8 *data; 1485 error = vm_allocate ( mach_task_self (), (vm_address_t *) &data, dataSize, true /*anywhere*/ ) ; 1486 if (error) 1487 break; 1488 1489 { 1490 UInt8 * exportCursor = data ; 1491 for( unsigned index=0; index < numDCLs; ++index ) 1492 { 1493 NuDCL * dcl = ((NuDCL**)inDCLList)[ index ] ; 1494 *(UInt32*)exportCursor = dcl->GetExportIndex() ; 1495 1496#ifndef __LP64__ 1497 ROSETTA_ONLY( 1498 { 1499 *(UInt32*)exportCursor = OSSwapInt32(*(UInt32*)exportCursor); 1500 } 1501 ); 1502#endif 1503 exportCursor += sizeof( UInt32 ) ; 1504 1505 dcl->Export( (IOVirtualAddress*) & exportCursor, mBufferRanges, mBufferRangeCount ) ; 1506 } 1507 } 1508 1509 uint32_t outputCnt = 0; 1510 const uint64_t inputs[4] = {notificationType, numDCLs, (uint64_t) data, dataSize}; 1511 error = IOConnectCallScalarMethod(mDevice.GetUserClientConnection(), 1512 Device::MakeSelectorWithObject( kLocalIsochPort_Notify_d, mKernPortRef ), 1513 inputs,4,NULL,&outputCnt); 1514 vm_deallocate( mach_task_self (), (vm_address_t) data, dataSize ) ; 1515 break ; 1516 } 1517 1518 case kFWNuDCLModifyJumpNotification: 1519 { 1520 unsigned pairCount = numDCLs << 1 ; 1521 1522 unsigned dcls[ pairCount ] ; 1523 1524 { 1525 unsigned index = 0 ; 1526 unsigned pairIndex=0; 1527 1528 while( pairIndex < pairCount ) 1529 { 1530 NuDCL * theDCL = ((NuDCL**)inDCLList)[ index++ ] ; 1531 dcls[ pairIndex ] = theDCL->GetExportIndex() ; 1532#ifndef __LP64__ 1533 ROSETTA_ONLY( 1534 { 1535 dcls[ pairIndex ] = OSSwapInt32(dcls[ pairIndex ]); 1536 } 1537 ); 1538#endif 1539 pairIndex += 1; 1540 1541 1542 if (theDCL->GetBranch()) 1543 dcls[ pairIndex ] = theDCL->GetBranch()->GetExportIndex() ; 1544 else 1545 dcls[ pairIndex ] = 0; 1546#ifndef __LP64__ 1547 ROSETTA_ONLY( 1548 { 1549 dcls[ pairIndex ] = OSSwapInt32(dcls[ pairIndex ]); 1550 } 1551 ); 1552#endif 1553 pairIndex += 1; 1554 } 1555 } 1556 1557 uint32_t outputCnt = 0; 1558 size_t outputStructSize = 0 ; 1559 const uint64_t inputs[2] = {notificationType, numDCLs}; 1560 error = IOConnectCallMethod(mDevice.GetUserClientConnection(), 1561 Device::MakeSelectorWithObject( kLocalIsochPort_Notify_d, mKernPortRef ), 1562 inputs,2, 1563 dcls,sizeof( dcls ), 1564 NULL,&outputCnt, 1565 NULL,&outputStructSize); 1566 break ; 1567 } 1568 1569 case kFWNuDCLUpdateNotification: 1570 { 1571 unsigned dcls[ numDCLs ] ; 1572 1573 for( unsigned index=0; index < numDCLs; ++index ) 1574 { 1575 dcls[ index ] = ((NuDCL*)inDCLList[ index ])->GetExportIndex() ; 1576#ifndef __LP64__ 1577 ROSETTA_ONLY( 1578 { 1579 dcls[ index ] = OSSwapInt32(dcls[ index ]); 1580 } 1581 ); 1582#endif 1583 } 1584 1585 uint32_t outputCnt = 0; 1586 size_t outputStructSize = 0 ; 1587 const uint64_t inputs[2] = {notificationType, numDCLs}; 1588 error = IOConnectCallMethod(mDevice.GetUserClientConnection(), 1589 Device::MakeSelectorWithObject( kLocalIsochPort_Notify_d, mKernPortRef ), 1590 inputs,2, 1591 dcls,sizeof( dcls ), 1592 NULL,&outputCnt, 1593 NULL,&outputStructSize); 1594 break ; 1595 } 1596 1597 case kFWDCLUpdateNotification: 1598 case kFWDCLModifyNotification: 1599 { 1600 error = kIOReturnUnsupported ; 1601 } 1602 1603 default: 1604 error = kIOReturnBadArgument ; 1605 } 1606 1607 return error ; 1608 } 1609 1610#pragma mark - 1611 // ============================================================ 1612 // 1613 // LocalIsochPortCOM 1614 // 1615 // ============================================================ 1616 1617 LocalIsochPortCOM::LocalIsochPortCOM( Device& userclient, bool talking, DCLCommand* program, UInt32 startEvent, 1618 UInt32 startState, UInt32 startMask, IOVirtualRange programRanges[], UInt32 programRangeCount, 1619 IOVirtualRange bufferRanges[], UInt32 bufferRangeCount, IOFWIsochPortOptions options ) 1620 : LocalIsochPort( reinterpret_cast<const IUnknownVTbl &>( sInterface ), userclient, talking, program, 1621 startEvent, startState, startMask, programRanges, 1622 programRangeCount, bufferRanges, bufferRangeCount, options ) 1623 { 1624 } 1625 1626 LocalIsochPortCOM::~LocalIsochPortCOM() 1627 { 1628 } 1629 1630 IUnknownVTbl** 1631 LocalIsochPortCOM::Alloc( Device & userclient, Boolean talking, DCLCommand * program, 1632 UInt32 startEvent, UInt32 startState, UInt32 startMask, 1633 IOVirtualRange programRanges[], UInt32 programRangeCount, 1634 IOVirtualRange bufferRanges[], UInt32 bufferRangeCount, 1635 IOFWIsochPortOptions options ) 1636 { 1637 LocalIsochPortCOM* me = nil ; 1638 1639 try 1640 { 1641 me = new LocalIsochPortCOM ( userclient, (bool)talking, program, startEvent, startState, startMask, 1642 programRanges, programRangeCount, bufferRanges, bufferRangeCount, options ) ; 1643 } 1644 catch(...) 1645 { 1646 } 1647 1648 return ( nil == me ) ? nil : reinterpret_cast < IUnknownVTbl ** > ( & me->GetInterface () ) ; 1649 } 1650 1651 HRESULT 1652 LocalIsochPortCOM::QueryInterface ( REFIID iid, void ** ppv ) 1653 { 1654 HRESULT result = S_OK ; 1655 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; 1656 1657 *ppv = nil ; 1658 1659 if ( CFEqual(interfaceID, IUnknownUUID) 1660 || CFEqual(interfaceID, kIOFireWireLocalIsochPortInterfaceID ) 1661 || CFEqual( interfaceID, kIOFireWireLocalIsochPortInterfaceID_v2 ) 1662#if 0 1663 || CFEqual( interfaceID, kIOFireWireLocalIsochPortInterfaceID_v3 ) // don't support this yet... 1664#endif 1665 || CFEqual( interfaceID, kIOFireWireLocalIsochPortInterfaceID_v4 ) 1666 || CFEqual( interfaceID, kIOFireWireLocalIsochPortInterfaceID_v5 ) 1667 ) 1668 { 1669 * ppv = & GetInterface () ; 1670 AddRef () ; 1671 } 1672 else 1673 { 1674 DebugLog("unknown local isoch port interface UUID\n") ; 1675 1676 * ppv = nil ; 1677 result = E_NOINTERFACE ; 1678 } 1679 1680 :: CFRelease ( interfaceID ) ; 1681 return result ; 1682 } 1683 1684 IOReturn 1685 LocalIsochPortCOM::SModifyJumpDCL( 1686 IOFireWireLibLocalIsochPortRef self, 1687 DCLJump * jump, 1688 DCLLabel * label) 1689 { 1690 return IOFireWireIUnknown::InterfaceMap< LocalIsochPortCOM >::GetThis ( self )->ModifyJumpDCL ( jump, label ) ; 1691 } 1692 1693 // 1694 // utility functions 1695 // 1696 1697 void 1698 LocalIsochPortCOM::SPrintDCLProgram ( 1699 IOFireWireLibLocalIsochPortRef self , 1700 const DCLCommand * program , 1701 UInt32 length ) 1702 { 1703 DeviceCOM::SPrintDCLProgram ( nil, program, length ) ; 1704 } 1705 1706 IOReturn 1707 LocalIsochPortCOM::SModifyTransferPacketDCLSize ( 1708 PortRef self, 1709 DCLTransferPacket * dcl, 1710 IOByteCount newSize ) 1711 { 1712 IOReturn error = kIOReturnBadArgument ; 1713 1714 switch ( dcl->opcode ) 1715 { 1716 case kDCLSendPacketStartOp: 1717 //case kDCLSendPacketWithHeaderStartOp: 1718 case kDCLSendPacketOp: 1719 case kDCLReceivePacketStartOp: 1720 case kDCLReceivePacketOp: 1721 case kDCLReceiveBufferOp: 1722 error = IOFireWireIUnknown::InterfaceMap<LocalIsochPortCOM>::GetThis( self )->ModifyTransferPacketDCLSize( dcl, newSize ) ; 1723 } 1724 1725 return error ; 1726 } 1727 1728 IOReturn 1729 LocalIsochPortCOM::SModifyTransferPacketDCLBuffer ( 1730 PortRef self, 1731 DCLTransferPacket * dcl, 1732 void * newBuffer ) 1733 { 1734 return kIOReturnUnsupported ; 1735 } 1736 1737 IOReturn 1738 LocalIsochPortCOM::SModifyTransferPacketDCL ( PortRef self, DCLTransferPacket * dcl, void * newBuffer, IOByteCount newSize ) 1739 { 1740 return kIOReturnUnsupported ; 1741 } 1742 1743 // 1744 // v4 1745 // 1746 1747 IOReturn 1748 LocalIsochPortCOM::S_SetFinalizeCallback( 1749 IOFireWireLibLocalIsochPortRef self, 1750 IOFireWireLibIsochPortFinalizeCallback finalizeCallback ) 1751 { 1752 LocalIsochPortCOM * me = IOFireWireIUnknown::InterfaceMap< LocalIsochPortCOM >::GetThis( self ) ; 1753 1754 me->mFinalizeCallback = finalizeCallback ; 1755 1756 return kIOReturnSuccess ; 1757 } 1758 1759 // 1760 // v5 (panther) 1761 // 1762 1763 IOReturn 1764 LocalIsochPortCOM::S_SetResourceUsageFlags ( 1765 IOFireWireLibLocalIsochPortRef self, 1766 IOFWIsochResourceFlags flags ) 1767 { 1768 return IOFireWireIUnknown::InterfaceMap< LocalIsochPortCOM >::GetThis( self )->SetResourceUsageFlags( flags ) ; 1769 } 1770 1771 IOReturn 1772 LocalIsochPortCOM::S_Notify( 1773 IOFireWireLibLocalIsochPortRef self, 1774 IOFWDCLNotificationType notificationType, 1775 void ** inDCLList, 1776 UInt32 numDCLs ) 1777 { 1778 return IOFireWireIUnknown::InterfaceMap< LocalIsochPortCOM >::GetThis( self )->Notify( notificationType, inDCLList, numDCLs ) ; 1779 } 1780} 1781