1/* 2* Copyright (c) 1998-2000 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* Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 24* 25* HISTORY 26* 8 June 1999 wgulland created. 27* 28*/ 29/* 30 $Log: IOFireWireUserClient.cpp,v $ 31 Revision 1.162 2011/12/17 00:57:00 calderon 32 <rdar://problem/9589404> IOFireWireUserClient allows arbitrarily sized stack allocations. 33 34 Revision 1.161 2009/05/08 01:10:34 calderon 35 <rdar://6863576> FireWire tracepoints should be inlined for performance 36 37 Revision 1.160 2009/03/07 00:37:23 calderon 38 Small change for 6641573 to give more useful debugging info 39 Add Firelog info.plist file 40 41 Revision 1.159 2009/03/06 18:45:15 calderon 42 <rdar://problem/6641573> Panic in IOFireWireFamily/SL 10A286 when hot-plugging Mackie Onyx 1200F 43 Add FireLog specific plist to work around XCode plist editor bug 44 Bump version 45 46 Revision 1.158 2008/12/12 04:43:57 collin 47 user space compare swap command fixes 48 49 Revision 1.157 2008/11/26 23:55:21 collin 50 fix user physical address spaces on K64 51 52 Revision 1.156 2008/11/20 01:59:12 calderon 53 More tracepoint logging 54 55 Revision 1.155 2008/11/11 01:12:03 calderon 56 First part of tracepoints logging 57 58 Revision 1.154 2008/05/07 03:27:59 collin 59 64 bit session ref support 60 61 Revision 1.153 2008/04/30 03:02:13 collin 62 publicize the exporter 63 64 Revision 1.152 2008/04/24 00:01:39 collin 65 more K640 66 67 Revision 1.151 2008/04/11 00:52:37 collin 68 some K64 changes 69 70 Revision 1.150 2008/04/02 01:42:50 collin 71 fix build failure 72 73 Revision 1.149 2007/10/16 16:50:21 ayanowit 74 Removed existing "work-in-progress" support for buffer-fill isoch. 75 76 Revision 1.148 2007/06/21 04:08:44 collin 77 *** empty log message *** 78 79 Revision 1.147 2007/05/04 06:05:26 collin 80 *** empty log message *** 81 82 Revision 1.146 2007/04/28 02:54:22 collin 83 *** empty log message *** 84 85 Revision 1.145 2007/04/28 01:42:35 collin 86 *** empty log message *** 87 88 Revision 1.144 2007/04/24 02:50:08 collin 89 *** empty log message *** 90 91 Revision 1.143 2007/03/14 01:01:13 collin 92 *** empty log message *** 93 94 Revision 1.142 2007/03/12 22:15:28 arulchan 95 mach_vm_address_t & io_user_reference_t changes 96 97 Revision 1.141 2007/03/10 07:48:25 collin 98 *** empty log message *** 99 100 Revision 1.140 2007/03/10 05:11:36 collin 101 *** empty log message *** 102 103 Revision 1.139 2007/03/10 04:15:25 collin 104 *** empty log message *** 105 106 Revision 1.138 2007/03/10 02:58:03 collin 107 *** empty log message *** 108 109 Revision 1.137 2007/03/09 23:57:53 collin 110 *** empty log message *** 111 112 Revision 1.136 2007/03/08 18:13:56 ayanowit 113 Fix for 5047793. A problem where user-space CompareSwap() was not checking lock results. 114 115 Revision 1.135 2007/03/08 02:37:09 collin 116 *** empty log message *** 117 118 Revision 1.134 2007/03/03 01:26:46 calderon 119 pico 120 121 Revision 1.133 2007/02/16 00:54:39 ayanowit 122 Working IRMAllocation callbacks from user-space :) 123 124 Revision 1.132 2007/02/16 00:28:25 ayanowit 125 More work on IRMAllocation APIs 126 127 Revision 1.131 2007/02/09 20:36:46 ayanowit 128 More Leopard IRMAllocation changes. 129 130 Revision 1.130 2007/02/07 06:35:20 collin 131 *** empty log message *** 132 133 Revision 1.129 2007/02/06 01:08:41 ayanowit 134 More work on Leopard features such as new User-space IRM allocation APIs. 135 136 Revision 1.128 2007/01/26 20:52:31 ayanowit 137 changes to user-space isoch stuff to support 64-bit apps. 138 139 Revision 1.127 2007/01/24 04:10:13 collin 140 *** empty log message *** 141 142 Revision 1.126 2007/01/05 00:11:00 ayanowit 143 yet more 64-bit changes. 144 145 Revision 1.124 2006/12/21 21:17:44 ayanowit 146 More changes necessary to eventually get support for 64-bit apps working (4222965). 147 148 Revision 1.123 2006/12/06 01:12:54 arulchan 149 AsyncStream Listener Merges to Dispatcher 150 151 Revision 1.122 2006/12/06 00:01:08 arulchan 152 Isoch Channel 31 Generic Receiver 153 154 Revision 1.121 2006/11/29 18:42:52 ayanowit 155 Modified the IOFireWireUserClient to use the Leopard externalMethod method of dispatch. 156 157 Revision 1.120 2006/09/09 01:59:56 collin 158 *** empty log message *** 159 160 Revision 1.119 2006/08/16 01:41:41 collin 161 *** empty log message *** 162 163 Revision 1.118 2006/07/07 20:18:25 calderon 164 4227201: SpeedMap and HopCount table reductions. 165 166 Revision 1.117 2006/02/27 19:03:18 niels 167 *** empty log message *** 168 169 Revision 1.116 2006/02/09 00:21:51 niels 170 merge chardonnay branch to tot 171 172 Revision 1.110.4.4 2006/01/31 04:49:51 collin 173 *** empty log message *** 174 175 Revision 1.110.4.2 2005/08/17 03:33:57 collin 176 *** empty log message *** 177 178 Revision 1.110.4.1 2005/07/23 00:30:44 collin 179 *** empty log message *** 180 181 Revision 1.110 2005/01/18 23:40:16 collin 182 Revision 1.109 2004/09/16 04:28:21 collin 183 Revision 1.108 2004/05/12 00:00:08 niels 184 3626775 - Brego 7L8: Digidesign Pro Tools LE FireWire 002 system doesn't work 185 3641955 - Digi 002 Pro Tools LE fails to launch on 10.3.4 7H46 186 187 Revision 1.107 2004/03/25 00:08:59 niels 188 fix panic allocating large physical address spaces 189 190 Revision 1.106 2004/03/25 00:00:59 niels 191 fix panic allocating large physical address spaces 192 193 Revision 1.105 2004/03/25 00:00:23 niels 194 fix panic allocating large physical address spaces 195 196 Revision 1.104 2004/02/17 23:13:23 niels 197 Revision 1.103 2004/02/17 23:12:26 niels 198 Revision 1.102 2004/02/11 22:30:02 niels 199 Revision 1.101 2004/02/11 22:13:08 niels 200 fix final cut pro panic/object leak when calling TurnOffNotification on isoch channels in user space 201 202 Revision 1.100 2004/01/28 22:13:32 niels 203 Revision 1.99 2004/01/22 01:49:59 niels 204 fix user space physical address space getPhysicalSegments 205 206 Revision 1.98 2003/12/19 22:07:46 niels 207 send force stop when channel dies/system sleeps 208 209 Revision 1.97 2003/12/18 00:42:37 niels 210 Revision 1.96 2003/11/14 01:00:53 collin 211 Revision 1.95 2003/11/07 21:24:28 niels 212 Revision 1.94 2003/11/07 21:01:18 niels 213 Revision 1.93 2003/11/05 00:29:42 niels 214 Revision 1.92 2003/11/03 19:11:35 niels 215 fix local config rom reading; fix 3401223 216 217 Revision 1.91 2003/10/31 02:40:58 niels 218 Revision 1.90 2003/09/20 00:54:17 collin 219 Revision 1.89 2003/09/16 21:40:51 collin 220 Revision 1.88 2003/09/11 20:59:46 collin 221 Revision 1.87 2003/09/04 19:43:34 collin 222 Revision 1.86 2003/09/02 23:48:12 collin 223 Revision 1.85 2003/09/02 22:58:55 collin 224 Revision 1.84 2003/08/30 00:16:45 collin 225 Revision 1.83 2003/08/26 05:23:34 niels 226 Revision 1.82 2003/08/26 05:11:21 niels 227 Revision 1.81 2003/08/25 08:39:16 niels 228 Revision 1.80 2003/08/20 18:48:43 niels 229 Revision 1.79 2003/08/19 01:48:54 niels 230 Revision 1.78 2003/08/14 19:46:06 niels 231 Revision 1.77 2003/08/14 17:47:33 niels 232 Revision 1.76 2003/08/08 22:30:32 niels 233 Revision 1.75 2003/08/08 21:03:27 gecko1 234 Merge max-rec clipping code into TOT 235 236 Revision 1.74 2003/07/26 04:47:24 collin 237 Revision 1.73 2003/07/24 20:49:48 collin 238 Revision 1.72 2003/07/24 06:30:58 collin 239 Revision 1.71 2003/07/24 03:06:27 collin 240 Revision 1.70 2003/07/22 10:49:47 niels 241 Revision 1.69 2003/07/21 07:29:48 niels 242 Revision 1.68 2003/07/21 06:52:59 niels 243 merge isoch to TOT 244 245 Revision 1.66.2.5 2003/07/21 06:44:45 niels 246 Revision 1.66.2.4 2003/07/18 00:17:42 niels 247 Revision 1.66.2.3 2003/07/11 18:15:34 niels 248 Revision 1.66.2.2 2003/07/09 21:24:01 niels 249 Revision 1.66.2.1 2003/07/01 20:54:07 niels 250 isoch merge 251 252 Revision 1.66 2003/06/12 21:27:14 collin 253 Revision 1.65 2003/06/07 01:30:40 collin 254 Revision 1.64 2003/06/05 01:19:31 niels 255 fix crash on close 256 257 Revision 1.63 2003/04/22 02:45:28 collin 258 Revision 1.62 2003/03/17 01:05:22 collin 259 Revision 1.61 2003/03/01 00:10:07 collin 260 Revision 1.60 2002/11/20 00:34:27 niels 261 fix minor bug in getAsyncTargetAndMethodForIndex 262 263 Revision 1.59 2002/10/18 23:29:45 collin 264 fix includes, fix cast which fails on new compiler 265 266 Revision 1.58 2002/10/17 00:29:44 collin 267 reenable FireLog 268 269 Revision 1.57 2002/10/16 21:42:00 niels 270 no longer panic trying to get config directory on local node.. still can't get the directory, however 271 272 Revision 1.56 2002/09/25 00:27:25 niels 273 flip your world upside-down 274 275 Revision 1.55 2002/09/12 22:41:54 niels 276 add GetIRMNodeID() to user client 277 278*/ 279 280// public 281#import "IOFireWireFamilyCommon.h" 282#import "IOFireWireNub.h" 283#import "IOLocalConfigDirectory.h" 284#import "IOFireWireController.h" 285#import "IOFireWireDevice.h" 286#import "IOFWDCLProgram.h" 287 288#import <sys/proc.h> 289#import <IOKit/IOMessage.h> 290#include <IOKit/IOKitKeysPrivate.h> 291 292#if FIRELOG 293#import <IOKit/firewire/FireLog.h> 294#endif 295 296// protected 297#import <IOKit/firewire/IOFireWireLink.h> 298 299// private 300#import "IOFireWireUserClient.h" 301#import "IOFWUserPseudoAddressSpace.h" 302#import "IOFWUserPhysicalAddressSpace.h" 303#import "IOFWUserIsochChannel.h" 304#import "IOFWUserIsochPort.h" 305#import "IOFireWireLibPriv.h" 306#import "IOFireWireLocalNode.h" 307#import "IOFWUserCommand.h" 308#import "IOFWUserObjectExporter.h" 309#import "IOLocalConfigDirectory.h" 310#import "IOFWUserAsyncStreamListener.h" 311#import "IOFWUserVectorCommand.h" 312#import "IOFWUserPHYPacketListener.h" 313 314#if IOFIREWIREUSERCLIENTDEBUG > 0 315 316#undef super 317#define super OSObject 318 319OSDefineMetaClassAndStructors( IOFWUserDebugInfo, OSObject ) 320 321bool 322IOFWUserDebugInfo::init( IOFireWireUserClient & userClient ) 323{ 324 if ( ! super::init() ) 325 return false ; 326 327 fUserClient = & userClient ; 328// fIsochCallbacks = OSNumber::withNumber( (long long unsigned)0, 64 ) ; 329// if ( !fIsochCallbacks ) 330// return false ; 331 332 return true ; 333} 334 335bool 336IOFWUserDebugInfo::serialize ( 337 OSSerialize * s ) const 338{ 339 s->clearText() ; 340 341 const unsigned objectCount = 1 ; 342 const OSObject * objects[ objectCount ] = 343 { 344 fUserClient->fExporter 345// , fIsochCallbacks 346 } ; 347 348 const OSSymbol * keys[ objectCount ] = 349 { 350 OSSymbol::withCStringNoCopy("user objects") 351// , OSSymbol::withCStringNoCopy( "total isoch callbacks" ) 352 } ; 353 354 OSDictionary * dict = OSDictionary::withObjects( objects, keys, objectCount ) ; 355 if ( !dict ) 356 return false ; 357 358 bool result = dict->serialize( s ) ; 359 dict->release() ; 360 361 return result ; 362} 363 364void 365IOFWUserDebugInfo::free () 366{ 367// if ( fIsochCallbacks ) 368// fIsochCallbacks->release() ; 369 OSObject::free() ; 370} 371 372#endif 373 374#pragma mark - 375 376#undef super 377#define super IOUserClient 378 379OSDefineMetaClassAndStructors(IOFireWireUserClient, super ) ; 380 381 382bool IOFireWireUserClient::initWithTask( 383 task_t owningTask, void * securityToken, UInt32 type, 384 OSDictionary * properties) 385{ 386 if( properties ) 387 properties->setObject( "IOUserClientCrossEndianCompatible" , kOSBooleanTrue); 388 389 bool res = IOUserClient::initWithTask( owningTask, securityToken, type, properties ); 390 391 fTask = owningTask; 392 393 return res; 394} 395 396bool 397IOFireWireUserClient::start( IOService * provider ) 398{ 399 if (!OSDynamicCast(IOFireWireNub, provider)) 400 return false ; 401 402 if ( ! super::start ( provider ) ) 403 return false; 404 405 fOwner = (IOFireWireNub *)provider; 406 fOwner->retain(); 407 408 FWTrace( kFWTUserClient, kTPUserClientStart, (uintptr_t)(fOwner->getController()->getLink()), 0, 0, 0 ); 409 410 // 411 // init object table 412 // 413 fObjectTable[0] = NULL ; 414 fObjectTable[1] = this ; 415 fObjectTable[2] = getOwner()->getBus() ; 416 417 // initialize notification structures 418 fBusResetAsyncNotificationRef[0] = 0 ; 419 fBusResetDoneAsyncNotificationRef[0] = 0 ; 420 421 bool result = true ; 422 423 fExporter = IOFWUserObjectExporter::createWithOwner( this ); 424 425 if ( ! fExporter ) 426 result = false ; 427 428#if IOFIREWIREUSERCLIENTDEBUG > 0 429 if (result) 430 { 431 fDebugInfo = OSTypeAlloc( IOFWUserDebugInfo ); 432 if ( fDebugInfo && ! fDebugInfo->init( *this ) ) 433 { 434 fDebugInfo->release() ; 435 fDebugInfo = NULL ; 436 437 ErrorLog( "Couldn't create statistics object\n" ) ; 438 } 439 440 if ( fDebugInfo ) 441 setProperty( "Debug Info", fDebugInfo ) ; 442 } 443#endif 444 445#if 0 446 // turn off because sadly the proc structure is now opaque 447 448 // borrowed from bsd/vm/vm_unix.c, function pid_for_task() which has some other weird crap 449 // going on too... I just took this part: 450 if ( result ) 451 { 452 proc * p = (proc *)get_bsdtask_info( fTask ); 453 OSNumber* pidProp = OSNumber::withNumber( p->p_pid, sizeof(p->p_pid) * 8 ) ; 454 if ( pidProp ) 455 { 456 setProperty( "Owning PID", pidProp ) ; 457 pidProp->release() ; // property table takes a reference 458 } 459 else 460 result = false ; 461 } 462#endif 463 464 return result ; 465} 466 467void 468IOFireWireUserClient::free() 469{ 470 if ( fOwner ) { 471 FWTrace( kFWTUserClient, kTPUserClientFree, (uintptr_t)(fOwner->getController()->getLink()), (uintptr_t)this, 0, 0 ); 472 } else { 473 FWTrace( kFWTUserClient, kTPUserClientFree, 0xdeadbeef, (uintptr_t)this, 0, 0 ); 474 } 475 476 DebugLog( "free user client %p\n", this ) ; 477 478#if IOFIREWIREUSERCLIENTDEBUG > 0 479 if ( fDebugInfo ) 480 fDebugInfo->release() ; 481#endif 482 483 if ( fExporter ) 484 { 485 fExporter->release() ; 486 fExporter = NULL ; 487 } 488 489 if ( fOwner ) 490 { 491 fOwner->release() ; 492 } 493 494 super::free () ; 495} 496 497IOReturn 498IOFireWireUserClient::clientClose () 499{ 500 FWTrace( kFWTUserClient, kTPUserClientClientClose, (uintptr_t)(fOwner->getController()->getLink()), 0, 0, 0 ); 501 502 clipMaxRec2K( false ); // Make sure maxRec isn't clipped 503 504 IOReturn result = userClose() ; 505 506 if ( getProvider() && fOwner->isOpen() ) 507 { 508 DebugLog("IOFireWireUserClient::clientClose(): client left user client open, should call close. Closing...\n") ; 509 } 510 else if ( result == kIOReturnNotOpen ) 511 { 512 result = kIOReturnSuccess ; 513 } 514 515 if ( !terminate() ) 516 { 517 IOLog("IOFireWireUserClient::clientClose: terminate failed!, getOwner()->isOpen( this ) returned %u\n", getOwner()->isOpen(this)) ; 518 } 519 520 return kIOReturnSuccess; 521} 522 523IOReturn 524IOFireWireUserClient::clientDied () 525{ 526 if ( fOwner ) { 527 FWTrace( kFWTUserClient, kTPUserClientClientDied, (uintptr_t)(fOwner->getController()->getLink()), 1, 0, 0 ); 528 } else { 529 FWTrace( kFWTUserClient, kTPUserClientClientDied, 0xdeadbeef, 1, 0, 0 ); 530 } 531 532 if ( fOwner ) 533 { 534 FWTrace( kFWTUserClient, kTPUserClientClientDied, (uintptr_t)(fOwner->getController()->getLink()), 2, 0, 0 ); 535 fOwner->getBus()->resetBus() ; 536 } 537 538 IOReturn error = clientClose () ; 539 540 return error ; 541} 542 543IOReturn 544IOFireWireUserClient::setProperties ( 545 OSObject * properties ) 546{ 547 IOReturn result = kIOReturnSuccess ; 548 549 OSDictionary* dict = OSDynamicCast( OSDictionary, properties ) ; 550 551 if ( dict ) 552 { 553 OSObject* value = dict->getObject( "unsafe bus resets" ) ; 554 555 if ( value and OSDynamicCast(OSNumber, value ) ) 556 { 557 fUnsafeResets = ( ((OSNumber*)value)->unsigned8BitValue() != 0 ) ; 558 } 559 else 560 { 561 result = super::setProperties ( properties ) ; 562 } 563 } 564 else 565 result = super::setProperties ( properties ) ; 566 567 return result ; 568} 569 570#pragma mark - 571 572 573static UInt32 getSelectorObjectLookupIndex(UInt32 selector) 574{ 575 UInt32 selectorObjectLookupIndex = 1; // Note: A 1 here specifies use of the IOFireWireUserClient object 576 577 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 578 // NOTE: If the selector is not in this lookup table, it is handled directly by the IOFireWireUserClient 579 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 580 switch (selector) 581 { 582 ///////////////////////////////////////////////////////////////////////// 583 // The follwing selectors all are handled by the IOFireWireBus 584 ///////////////////////////////////////////////////////////////////////// 585 case kCycleTime: 586 case kGetBusCycleTime: 587 selectorObjectLookupIndex = 2; // Note: A 2 here specifies use of the IOFireWireBus object 588 break; 589 590 ///////////////////////////////////////////////////////////////////////////////// 591 // The follwing selectors all are handled by object exporter managed objects 592 ///////////////////////////////////////////////////////////////////////////////// 593 case kPhysicalAddrSpace_GetSegmentCount_d: // Handled by a IOFWUserPhysicalAddressSpace object 594 case kIsochPort_AllocatePort_d: // Handled by a IOFWUserLocalIsochPort object 595 case kIsochPort_ReleasePort_d: // Handled by a IOFWUserLocalIsochPort object 596 case kIsochPort_Start_d: // Handled by a IOFWUserLocalIsochPort object 597 case kIsochPort_Stop_d: // Handled by a IOFWUserLocalIsochPort object 598 case kLocalIsochPort_ModifyJumpDCL_d: // Handled by a IOFWUserLocalIsochPort object 599 case kLocalIsochPort_Notify_d: // Handled by a IOFWUserLocalIsochPort object 600 case kIsochChannel_UserReleaseChannelComplete_d: // Handled by a IOFWUserIsochChannel object 601 case kCommand_Cancel_d: // Handled by a IOFWCommand object 602 case kIsochPort_SetIsochResourceFlags_d: // Handled by a IOFWLocalIsochPort object 603 case kVectorCommandSubmit: // Handled by a IOFWUserVectorCommand object 604 case kVectorCommandSetBuffers: // Handled by a IOFWUserVectorCommand object 605 case kPHYPacketListenerSetPacketCallback: // Handled by a IOFWUserPHYPacketListener object 606 case kPHYPacketListenerSetSkippedCallback: // Handled by a IOFWUserPHYPacketListener object 607 case kPHYPacketListenerActivate: // Handled by a IOFWUserPHYPacketListener object 608 case kPHYPacketListenerDeactivate: // Handled by a IOFWUserPHYPacketListener object 609 case kPHYPacketListenerClientCommandIsComplete: // Handled by a IOFWUserPHYPacketListener object 610 selectorObjectLookupIndex = 0; // Note: A 0 here specifies a lookup into the object exporter! 611 break; 612 613 default: 614 // Any other selector is handled by the IOFireWireUserClient! 615 break; 616 }; 617 return selectorObjectLookupIndex; 618} 619 620IOReturn 621IOFireWireUserClient::externalMethod( uint32_t selector, 622 IOExternalMethodArguments * arguments, 623 IOExternalMethodDispatch * dispatch, 624 OSObject * target, 625 void * reference) 626{ 627 IOReturn result = kIOReturnBadArgument; 628 IOService *targetObject; 629 630 UInt32 actualSelector = selector & 0xFFFF ; 631 if ( actualSelector >= kNumMethods ) 632 return result; 633 634 targetObject = fObjectTable[ getSelectorObjectLookupIndex(actualSelector)] ; 635 636 if ( !targetObject ) 637 { 638 const OSObject * userObject = fExporter->lookupObject( (UserObjectHandle)( selector >> 16 ) ) ; 639 640 targetObject = (IOService*)userObject ; // "interesting code" note: 641 // when we don't have an object set in our method table, 642 // the object handle is encoded in the upper 16 bits of the 643 // method index... 644 // We extract the object handle here to get the object to call... 645 646 if (targetObject) 647 { 648 (targetObject)->release() ; // exporter retains returned objects, we have to release it here.. 649 // hopefully no one will release the object until we're done.. 650 } 651 else 652 return result; 653 } 654 655 // Dispatch the method call 656 switch (actualSelector) 657 { 658 case kOpen: 659 result = ((IOFireWireUserClient*) targetObject)->userOpen(); 660 break; 661 662 case kOpenWithSessionRef: 663 result = ((IOFireWireUserClient*) targetObject)->userOpenWithSessionRef((IOFireWireLib::UserObjectHandle) arguments->scalarInput[0]); 664 break; 665 666 case kClose: 667 result = ((IOFireWireUserClient*) targetObject)->userClose(); 668 break; 669 670 case kReadQuad: 671 result = ((IOFireWireUserClient*) targetObject)-> 672 readQuad((const ReadQuadParams*) arguments->structureInput, 673 (UInt32*) arguments->structureOutput); 674 break; 675 676 case kRead: 677 result = ((IOFireWireUserClient*) targetObject)-> 678 read((const ReadParams*) arguments->structureInput, 679 (IOByteCount*) arguments->structureOutput); 680 break; 681 682 case kWriteQuad: 683 result = ((IOFireWireUserClient*) targetObject)->writeQuad((const WriteQuadParams*) arguments->structureInput); 684 break; 685 686 case kWrite: 687 result = ((IOFireWireUserClient*) targetObject)-> 688 write((const WriteParams*) arguments->structureInput, 689 (IOByteCount*) arguments->structureOutput); 690 break; 691 692 case kCompareSwap: 693 result = ((IOFireWireUserClient*) targetObject)-> 694 compareSwap((const CompareSwapParams*) arguments->structureInput, 695 (UInt32*) arguments->structureOutput); 696 break; 697 698 case kBusReset: 699 result = ((IOFireWireUserClient*) targetObject)->busReset(); 700 break; 701 702 case kCycleTime: 703 { 704 UInt32 cycleTime; 705 UInt64 upTime; 706 result = ((IOFireWireController*) targetObject)->getCycleTimeAndUpTime(cycleTime, upTime); 707 arguments->scalarOutput[0] = cycleTime; 708 arguments->scalarOutput[1] = upTime; 709 } 710 break; 711 712 case kGetGenerationAndNodeID: 713 { 714 UInt32 outGeneration; 715 UInt32 outNodeID; 716 result = ((IOFireWireUserClient*) targetObject)->getGenerationAndNodeID(&outGeneration,&outNodeID); 717 arguments->scalarOutput[0] = outGeneration; 718 arguments->scalarOutput[1] = outNodeID; 719 } 720 break; 721 722 case kGetLocalNodeID: 723 { 724 UInt32 outLocalNodeID; 725 result = ((IOFireWireUserClient*) targetObject)->getLocalNodeID(&outLocalNodeID); 726 arguments->scalarOutput[0] = outLocalNodeID; 727 } 728 break; 729 730 case kGetResetTime: 731 result = ((IOFireWireUserClient*) targetObject)->getResetTime((AbsoluteTime*) arguments->structureOutput); 732 break; 733 734 case kReleaseUserObject: 735 result = ((IOFireWireUserClient*) targetObject)->releaseUserObject((UserObjectHandle)arguments->scalarInput[0]); 736 break; 737 738 case kGetOSStringData: 739 { 740 UInt32 outTextLength; 741 result = ((IOFireWireUserClient*) targetObject)->getOSStringData((UserObjectHandle)arguments->scalarInput[0], 742 (UInt32)arguments->scalarInput[1], 743 (mach_vm_address_t)arguments->scalarInput[2], 744 &outTextLength); 745 arguments->scalarOutput[0] = outTextLength; 746 } 747 break; 748 749 case kGetOSDataData: 750 { 751 IOByteCount outDataLen; 752 result = ((IOFireWireUserClient*) targetObject)->getOSDataData((UserObjectHandle)arguments->scalarInput[0], 753 (IOByteCount)arguments->scalarInput[1], 754 (mach_vm_address_t)arguments->scalarInput[2], 755 &outDataLen); 756 arguments->scalarOutput[0] = outDataLen; 757 } 758 break; 759 760 case kLocalConfigDirectory_Create: 761 { 762 UserObjectHandle outDir; 763 result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Create(&outDir); 764 arguments->scalarOutput[0] = (uint64_t) outDir; 765 } 766 break; 767 768 case kLocalConfigDirectory_AddEntry_Buffer: 769 result = ((IOFireWireUserClient*) targetObject)-> 770 localConfigDirectory_addEntry_Buffer((UserObjectHandle)arguments->scalarInput[0], 771 (int)arguments->scalarInput[1], 772 (char *)arguments->scalarInput[2], 773 (UInt32)arguments->scalarInput[3], 774 (const char *)arguments->scalarInput[4], 775 (UInt32)arguments->scalarInput[5]); 776 break; 777 778 case kLocalConfigDirectory_AddEntry_UInt32: 779 result = ((IOFireWireUserClient*) targetObject)-> 780 localConfigDirectory_addEntry_UInt32((UserObjectHandle)arguments->scalarInput[0], 781 (int)arguments->scalarInput[1], 782 (UInt32)arguments->scalarInput[2], 783 (const char *)arguments->scalarInput[3], 784 (UInt32)arguments->scalarInput[4]); 785 break; 786 787 case kLocalConfigDirectory_AddEntry_FWAddr: 788 result = ((IOFireWireUserClient*) targetObject)-> 789 localConfigDirectory_addEntry_FWAddr((UserObjectHandle)arguments->scalarInput[0], 790 (int)arguments->scalarInput[1], 791 (const char *)arguments->scalarInput[2], 792 (UInt32)arguments->scalarInput[3], 793 (FWAddress *) arguments->structureInput); 794 break; 795 796 case kLocalConfigDirectory_AddEntry_UnitDir: 797 // TODO - Note: This wasn't hooked-up in Tiger either! 798 break; 799 800 case kLocalConfigDirectory_Publish: 801 result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Publish((UserObjectHandle)arguments->scalarInput[0]); 802 break; 803 804 case kLocalConfigDirectory_Unpublish: 805 result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Unpublish((UserObjectHandle)arguments->scalarInput[0]); 806 break; 807 808 case kPseudoAddrSpace_Allocate: 809 result = ((IOFireWireUserClient*) targetObject)-> 810 addressSpace_Create((AddressSpaceCreateParams *) arguments->structureInput, 811 (UserObjectHandle *) arguments->structureOutput); 812 break; 813 814 case kPseudoAddrSpace_GetFWAddrInfo: 815 result = ((IOFireWireUserClient*) targetObject)-> 816 addressSpace_GetInfo((UserObjectHandle)arguments->scalarInput[0], 817 (AddressSpaceInfo *) arguments->structureOutput); 818 break; 819 820 case kPseudoAddrSpace_ClientCommandIsComplete: 821 result = ((IOFireWireUserClient*) targetObject)-> 822 addressSpace_ClientCommandIsComplete((UserObjectHandle)arguments->scalarInput[0], 823 (FWClientCommandID)arguments->scalarInput[1], 824 (IOReturn)arguments->scalarInput[2]); 825 break; 826 827 case kPhysicalAddrSpace_Allocate: 828 { 829 UserObjectHandle outAddressSpaceHandle; 830 result = ((IOFireWireUserClient*) targetObject)->physicalAddressSpace_Create((mach_vm_size_t)arguments->scalarInput[0], 831 (mach_vm_address_t)arguments->scalarInput[1], 832 (UInt32)arguments->scalarInput[2], 833 &outAddressSpaceHandle); 834 arguments->scalarOutput[0] = (uint64_t) outAddressSpaceHandle; 835 } 836 break; 837 838 case kPhysicalAddrSpace_GetSegmentCount_d: 839 { 840 UInt32 outSegmentCount; 841 result = ((IOFWUserPhysicalAddressSpace*) targetObject)->getSegmentCount(&outSegmentCount); 842 arguments->scalarOutput[0] = outSegmentCount; 843 } 844 break; 845 846 case kPhysicalAddrSpace_GetSegments: 847 { 848 UInt32 outSegmentCount; 849 result = ((IOFireWireUserClient*) targetObject)->physicalAddressSpace_GetSegments((UserObjectHandle)arguments->scalarInput[0], 850 (UInt32)arguments->scalarInput[1], 851 (mach_vm_address_t)arguments->scalarInput[2], 852 &outSegmentCount); 853 arguments->scalarOutput[0] = outSegmentCount; 854 } 855 break; 856 857 case kConfigDirectory_Create: 858 { 859 UserObjectHandle outDirRef; 860 result = ((IOFireWireUserClient*) targetObject)->configDirectory_Create(&outDirRef); 861 arguments->scalarOutput[0] = (uint64_t) outDirRef; 862 } 863 break; 864 865 case kConfigDirectory_GetKeyType: 866 { 867 IOConfigKeyType outType; 868 result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetKeyType((UserObjectHandle)arguments->scalarInput[0], 869 (int)arguments->scalarInput[1], 870 &outType); 871 arguments->scalarOutput[0] = outType; 872 } 873 break; 874 875 case kConfigDirectory_GetKeyValue_UInt32: 876 { 877 UInt32 outValue; 878 UserObjectHandle outTextHandle; 879 UInt32 outTextLength; 880 result = ((IOFireWireUserClient*) targetObject)-> 881 configDirectory_GetKeyValue_UInt32((UserObjectHandle)arguments->scalarInput[0], 882 (int)arguments->scalarInput[1], 883 (UInt32)arguments->scalarInput[2], 884 &outValue, 885 &outTextHandle, 886 &outTextLength); 887 arguments->scalarOutput[0] = outValue; 888 arguments->scalarOutput[1] = (uint64_t) outTextHandle; 889 arguments->scalarOutput[2] = outTextLength; 890 } 891 break; 892 893 case kConfigDirectory_GetKeyValue_Data: 894 result = ((IOFireWireUserClient*) targetObject)-> 895 configDirectory_GetKeyValue_Data((UserObjectHandle)arguments->scalarInput[0], 896 (int)arguments->scalarInput[1], 897 (UInt32)arguments->scalarInput[2], 898 (GetKeyValueDataResults *) arguments->structureOutput); 899 break; 900 901 case kConfigDirectory_GetKeyValue_ConfigDirectory: 902 { 903 UserObjectHandle outDirHandle; 904 UserObjectHandle outTextHandle; 905 UInt32 outTextLength; 906 result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetKeyValue_ConfigDirectory((UserObjectHandle)arguments->scalarInput[0], 907 (int)arguments->scalarInput[1], 908 (UInt32)arguments->scalarInput[2], 909 &outDirHandle, 910 &outTextHandle, 911 &outTextLength); 912 arguments->scalarOutput[0] = (uint64_t) outDirHandle; 913 arguments->scalarOutput[1] = (uint64_t) outTextHandle; 914 arguments->scalarOutput[2] = outTextLength; 915 } 916 break; 917 918 case kConfigDirectory_GetKeyOffset_FWAddress: 919 result = ((IOFireWireUserClient*) targetObject)-> 920 configDirectory_GetKeyOffset_FWAddress((UserObjectHandle)arguments->scalarInput[0], 921 (int)arguments->scalarInput[1], 922 (UInt32)arguments->scalarInput[2], 923 (GetKeyOffsetResults *) arguments->structureOutput); 924 break; 925 926 case kConfigDirectory_GetIndexType: 927 { 928 IOConfigKeyType outType; 929 result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexType((UserObjectHandle)arguments->scalarInput[0], 930 (int)arguments->scalarInput[1], 931 &outType); 932 arguments->scalarOutput[0] = (IOConfigKeyType) outType; 933 } 934 break; 935 936 case kConfigDirectory_GetIndexKey: 937 { 938 int outKey; 939 result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexKey((UserObjectHandle)arguments->scalarInput[0], 940 (int)arguments->scalarInput[1], 941 &outKey); 942 arguments->scalarOutput[0] = outKey; 943 } 944 break; 945 946 case kConfigDirectory_GetIndexValue_UInt32: 947 // configDirectory_GetIndexValue_UInt32 948 { 949 UInt32 outKey; 950 result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexValue_UInt32((UserObjectHandle)arguments->scalarInput[0], 951 (int)arguments->scalarInput[1], 952 &outKey); 953 arguments->scalarOutput[0] = outKey; 954 } 955 break; 956 957 case kConfigDirectory_GetIndexValue_Data: 958 { 959 UserObjectHandle outDataHandle; 960 IOByteCount outDataLen; 961 result = ((IOFireWireUserClient*) targetObject)-> 962 configDirectory_GetIndexValue_Data((UserObjectHandle)arguments->scalarInput[0], 963 (int)arguments->scalarInput[1], 964 &outDataHandle, 965 &outDataLen); 966 arguments->scalarOutput[0] = (uint64_t) outDataHandle; 967 arguments->scalarOutput[1] = outDataLen; 968 } 969 break; 970 971 case kConfigDirectory_GetIndexValue_String: 972 { 973 UserObjectHandle outTextHandle; 974 UInt32 outTextLength; 975 result = ((IOFireWireUserClient*) targetObject)-> 976 configDirectory_GetIndexValue_String((UserObjectHandle)arguments->scalarInput[0], 977 (int)arguments->scalarInput[1], 978 &outTextHandle, 979 &outTextLength); 980 arguments->scalarOutput[0] = (uint64_t) outTextHandle; 981 arguments->scalarOutput[1] = outTextLength; 982 } 983 break; 984 985 case kConfigDirectory_GetIndexValue_ConfigDirectory: 986 { 987 UserObjectHandle outDirHandle; 988 result = ((IOFireWireUserClient*) targetObject)-> 989 configDirectory_GetIndexValue_ConfigDirectory((UserObjectHandle)arguments->scalarInput[0], 990 (int)arguments->scalarInput[1], 991 &outDirHandle); 992 arguments->scalarOutput[0] = (uint64_t) outDirHandle; 993 } 994 break; 995 996 case kConfigDirectory_GetIndexOffset_FWAddress: 997 result = ((IOFireWireUserClient*) targetObject)-> 998 configDirectory_GetIndexOffset_FWAddress((UserObjectHandle)arguments->scalarInput[0], 999 (int)arguments->scalarInput[1], 1000 (FWAddress *) arguments->structureOutput); 1001 break; 1002 1003 case kConfigDirectory_GetIndexOffset_UInt32: 1004 { 1005 UInt32 outValue; 1006 result = ((IOFireWireUserClient*) targetObject)-> 1007 configDirectory_GetIndexOffset_UInt32((UserObjectHandle)arguments->scalarInput[0], 1008 (int)arguments->scalarInput[1], 1009 &outValue); 1010 arguments->scalarOutput[0] = outValue; 1011 } 1012 break; 1013 1014 case kConfigDirectory_GetIndexEntry: 1015 { 1016 UInt32 outValue; 1017 result = ((IOFireWireUserClient*) targetObject)-> 1018 configDirectory_GetIndexEntry((UserObjectHandle)arguments->scalarInput[0], 1019 (int)arguments->scalarInput[1], 1020 &outValue); 1021 arguments->scalarOutput[0] = outValue; 1022 } 1023 break; 1024 1025 case kConfigDirectory_GetSubdirectories: 1026 { 1027 UserObjectHandle outIteratorHandle; 1028 result = ((IOFireWireUserClient*) targetObject)-> 1029 configDirectory_GetSubdirectories((UserObjectHandle)arguments->scalarInput[0], 1030 &outIteratorHandle); 1031 arguments->scalarOutput[0] = (uint64_t) outIteratorHandle; 1032 } 1033 break; 1034 1035 case kConfigDirectory_GetKeySubdirectories: 1036 { 1037 UserObjectHandle outIteratorHandle; 1038 result = ((IOFireWireUserClient*) targetObject)-> 1039 configDirectory_GetKeySubdirectories((UserObjectHandle)arguments->scalarInput[0], 1040 (int)arguments->scalarInput[1], 1041 &outIteratorHandle); 1042 arguments->scalarOutput[0] = (uint64_t) outIteratorHandle; 1043 } 1044 break; 1045 1046 case kConfigDirectory_GetType: 1047 { 1048 int outType; 1049 result = ((IOFireWireUserClient*) targetObject)-> 1050 configDirectory_GetType((UserObjectHandle)arguments->scalarInput[0],&outType); 1051 arguments->scalarOutput[0] = outType; 1052 } 1053 break; 1054 1055 case kConfigDirectory_GetNumEntries: 1056 { 1057 int outNumEntries; 1058 result = ((IOFireWireUserClient*) targetObject)-> 1059 configDirectory_GetNumEntries((UserObjectHandle)arguments->scalarInput[0],&outNumEntries); 1060 arguments->scalarOutput[0] = outNumEntries; 1061 } 1062 break; 1063 1064 case kIsochPort_GetSupported: 1065 { 1066 IOFWSpeed outMaxSpeed; 1067 UInt32 outChanSupportedHi; 1068 UInt32 outChanSupportedLo; 1069 result = ((IOFireWireUserClient*) targetObject)-> 1070 localIsochPort_GetSupported((UserObjectHandle)arguments->scalarInput[0], 1071 &outMaxSpeed, 1072 &outChanSupportedHi, 1073 &outChanSupportedLo); 1074 arguments->scalarOutput[0] = outMaxSpeed; 1075 arguments->scalarOutput[1] = outChanSupportedHi; 1076 arguments->scalarOutput[2] = outChanSupportedLo; 1077 } 1078 break; 1079 1080 case kIsochPort_AllocatePort_d: 1081 result = ((IOFWUserLocalIsochPort*) targetObject)->allocatePort((IOFWSpeed)arguments->scalarInput[0], 1082 (UInt32)arguments->scalarInput[1]); 1083 break; 1084 1085 case kIsochPort_ReleasePort_d: 1086 result = ((IOFWUserLocalIsochPort*) targetObject)->releasePort(); 1087 break; 1088 1089 case kIsochPort_Start_d: 1090 result = ((IOFWUserLocalIsochPort*) targetObject)->start(); 1091 break; 1092 1093 case kIsochPort_Stop_d: 1094 result = ((IOFWUserLocalIsochPort*) targetObject)->stop(); 1095 break; 1096 1097 case kLocalIsochPort_Allocate: 1098 result = ((IOFireWireUserClient*) targetObject)-> 1099 localIsochPort_Create((LocalIsochPortAllocateParams*) arguments->structureInput, 1100 (UserObjectHandle*) arguments->structureOutput); 1101 break; 1102 1103 case kLocalIsochPort_ModifyJumpDCL_d: 1104 result = ((IOFWUserLocalIsochPort*) targetObject)->modifyJumpDCL((UInt32)arguments->scalarInput[0], 1105 (UInt32)arguments->scalarInput[1]); 1106 break; 1107 1108 case kLocalIsochPort_Notify_d: 1109 if (arguments->scalarInput[0] == kFWNuDCLModifyNotification) 1110 { 1111 IOMemoryDescriptor * userDCLExportDesc = NULL ; 1112 IOReturn error ; 1113 UInt8 *pUserImportDCLBuffer; 1114 userDCLExportDesc = IOMemoryDescriptor::withAddressRange( arguments->scalarInput[2], 1115 arguments->scalarInput[3], 1116 kIODirectionOut, 1117 getOwningTask() ) ; 1118 // get map of program export data 1119 if ( userDCLExportDesc ) 1120 { 1121 error = userDCLExportDesc->prepare() ; 1122 } 1123 else 1124 error = kIOReturnVMError; 1125 1126 if ( !error ) 1127 { 1128 pUserImportDCLBuffer = new UInt8[ arguments->scalarInput[3] ] ; 1129 if ( !pUserImportDCLBuffer ) 1130 { 1131 error = kIOReturnVMError ; 1132 } 1133 } 1134 1135 if ( !error ) 1136 { 1137 unsigned byteCount = userDCLExportDesc->readBytes( 0, (void*)pUserImportDCLBuffer, arguments->scalarInput[3] ) ; 1138 if ( byteCount < arguments->scalarInput[3] ) 1139 { 1140 error = kIOReturnVMError ; 1141 } 1142 } 1143 1144 if ( !error ) 1145 { 1146 result = ((IOFWUserLocalIsochPort*) targetObject)->userNotify((UInt32)arguments->scalarInput[0], 1147 (UInt32)arguments->scalarInput[1], 1148 (void *) pUserImportDCLBuffer, 1149 arguments->scalarInput[3]); 1150 userDCLExportDesc->complete() ; 1151 userDCLExportDesc->release(); 1152 delete [] pUserImportDCLBuffer; 1153 } 1154 else 1155 { 1156 result = kIOReturnVMError; 1157 } 1158 } 1159 else 1160 result = ((IOFWUserLocalIsochPort*) targetObject)-> 1161 userNotify((UInt32)arguments->scalarInput[0], 1162 (UInt32)arguments->scalarInput[1], 1163 (void *) arguments->structureInput, 1164 arguments->structureInputSize); 1165 break; 1166 1167 case kLocalIsochPort_SetChannel: 1168 result = ((IOFireWireUserClient*) targetObject)-> 1169 localIsochPort_SetChannel((UserObjectHandle)arguments->scalarInput[0], 1170 (UserObjectHandle)arguments->scalarInput[1]); 1171 break; 1172 1173 case kIsochChannel_Allocate: 1174 { 1175 UserObjectHandle outChannelHandle; 1176 result = ((IOFireWireUserClient*) targetObject)-> 1177 isochChannel_Create((bool)arguments->scalarInput[0], 1178 (UInt32)arguments->scalarInput[1], 1179 (IOFWSpeed)arguments->scalarInput[2], 1180 &outChannelHandle); 1181 arguments->scalarOutput[0] = (uint64_t) outChannelHandle; 1182 } 1183 break; 1184 1185 case kIsochChannel_UserAllocateChannelBegin: 1186 { 1187 UInt32 outSpeed; 1188 UInt32 outChannel; 1189 result = ((IOFireWireUserClient*) targetObject)-> 1190 isochChannel_AllocateChannelBegin((UserObjectHandle)arguments->scalarInput[0], 1191 (UInt32)arguments->scalarInput[1], 1192 (UInt32)arguments->scalarInput[2], 1193 (UInt32)arguments->scalarInput[3], 1194 &outSpeed, 1195 &outChannel); 1196 arguments->scalarOutput[0] = outSpeed; 1197 arguments->scalarOutput[1] = outChannel; 1198 } 1199 break; 1200 1201 case kIsochChannel_UserReleaseChannelComplete_d: 1202 result = ((IOFWUserIsochChannel*) targetObject)->releaseChannelComplete(); 1203 break; 1204 1205 case kCommand_Cancel_d: 1206 result = ((IOFWCommand*) targetObject)->cancel((IOReturn)arguments->scalarInput[0]); 1207 break; 1208 1209 case kSeize: 1210 result = ((IOFireWireUserClient*) targetObject)->seize((IOOptionBits) arguments->scalarInput[0]); 1211 break; 1212 1213 case kFireLog: 1214 result = ((IOFireWireUserClient*) targetObject)-> 1215 firelog((const char*) arguments->structureInput,arguments->structureInputSize); 1216 break; 1217 1218 case kGetBusCycleTime: 1219 { 1220 UInt32 busTime; 1221 UInt32 cycleTime; 1222 result = ((IOFireWireBus*) targetObject)->getBusCycleTime(busTime,cycleTime); 1223 arguments->scalarOutput[0] = busTime; 1224 arguments->scalarOutput[1] = cycleTime; 1225 } 1226 break; 1227 1228 case kGetBusGeneration: 1229 { 1230 UInt32 outGeneration; 1231 result = ((IOFireWireUserClient*) targetObject)->getBusGeneration(&outGeneration); 1232 arguments->scalarOutput[0] = outGeneration; 1233 } 1234 break; 1235 1236 case kGetLocalNodeIDWithGeneration: 1237 { 1238 UInt32 outLocalNodeID; 1239 result = ((IOFireWireUserClient*) targetObject)-> 1240 getLocalNodeIDWithGeneration((UInt32)arguments->scalarInput[0],&outLocalNodeID); 1241 arguments->scalarOutput[0] = outLocalNodeID; 1242 } 1243 break; 1244 1245 case kGetRemoteNodeID: 1246 { 1247 UInt32 outRemoteNodeID; 1248 result = ((IOFireWireUserClient*) targetObject)-> 1249 getRemoteNodeID((UInt32)arguments->scalarInput[0],&outRemoteNodeID); 1250 arguments->scalarOutput[0] = outRemoteNodeID; 1251 } 1252 break; 1253 1254 case kGetSpeedToNode: 1255 { 1256 UInt32 outSpeed; 1257 result = ((IOFireWireUserClient*) targetObject)-> 1258 getSpeedToNode((UInt32)arguments->scalarInput[0],&outSpeed); 1259 arguments->scalarOutput[0] = outSpeed; 1260 } 1261 break; 1262 1263 case kGetSpeedBetweenNodes: 1264 { 1265 UInt32 outSpeed; 1266 result = ((IOFireWireUserClient*) targetObject)-> 1267 getSpeedBetweenNodes((UInt32)arguments->scalarInput[0], 1268 (UInt32)arguments->scalarInput[1], 1269 (UInt32)arguments->scalarInput[2], 1270 &outSpeed); 1271 arguments->scalarOutput[0] = outSpeed; 1272 } 1273 break; 1274 1275 case kGetIRMNodeID: 1276 { 1277 UInt32 irmNodeID; 1278 result = ((IOFireWireUserClient*) targetObject)-> 1279 getIRMNodeID((UInt32)arguments->scalarInput[0],&irmNodeID); 1280 arguments->scalarOutput[0] = irmNodeID; 1281 } 1282 break; 1283 1284 case kClipMaxRec2K: 1285 result = ((IOFireWireUserClient*) targetObject)->clipMaxRec2K((Boolean) arguments->scalarInput[0]); 1286 break; 1287 1288 case kIsochPort_SetIsochResourceFlags_d: 1289 result = ((IOFWLocalIsochPort*) targetObject)->setIsochResourceFlags((IOFWIsochResourceFlags) arguments->scalarInput[0]); 1290 break; 1291 1292 case kGetSessionRef: 1293 { 1294 IOFireWireSessionRef sessionRef=NULL; 1295 result = ((IOFireWireUserClient*) targetObject)->getSessionRef(&sessionRef); 1296 arguments->scalarOutput[0] = (uint64_t) sessionRef; 1297 } 1298 break; 1299 1300 case kAllocateIRMBandwidth: 1301 result = ((IOFireWireUserClient*) targetObject)->allocateIRMBandwidthInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]); 1302 break; 1303 1304 case kReleaseIRMBandwidth: 1305 result = ((IOFireWireUserClient*) targetObject)->releaseIRMBandwidthInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]); 1306 break; 1307 1308 case kAllocateIRMChannel: 1309 result = ((IOFireWireUserClient*) targetObject)->allocateIRMChannelInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]); 1310 break; 1311 1312 case kReleaseIRMChannel: 1313 result = ((IOFireWireUserClient*) targetObject)->releaseIRMChannelInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]); 1314 break; 1315 1316 case kAsyncStreamListener_Allocate: 1317 result = ((IOFireWireUserClient*) targetObject)-> 1318 asyncStreamListener_Create((FWUserAsyncStreamListenerCreateParams*) arguments->structureInput, 1319 (UserObjectHandle*) arguments->structureOutput); 1320 break; 1321 1322 case kAsyncStreamListener_ClientCommandIsComplete: 1323 result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_ClientCommandIsComplete((UserObjectHandle)arguments->scalarInput[0], 1324 (FWClientCommandID)arguments->scalarInput[1]); 1325 break; 1326 1327 case kAsyncStreamListener_GetOverrunCounter: 1328 { 1329 UInt32 counter = 0; 1330 result = ((IOFireWireUserClient*) targetObject)-> 1331 asyncStreamListener_GetOverrunCounter((UserObjectHandle)arguments->scalarInput[0], &counter); 1332 arguments->scalarOutput[0] = counter; 1333 } 1334 break; 1335 1336 case kAsyncStreamListener_SetFlags: 1337 result = ((IOFireWireUserClient*) targetObject)-> 1338 asyncStreamListener_SetFlags((UserObjectHandle)arguments->scalarInput[0], 1339 (UInt32)arguments->scalarInput[1]); 1340 break; 1341 1342 case kAsyncStreamListener_GetFlags: 1343 { 1344 UInt32 outFlags; 1345 result = ((IOFireWireUserClient*) targetObject)-> 1346 asyncStreamListener_GetFlags((UserObjectHandle)arguments->scalarInput[0], &outFlags); 1347 arguments->scalarOutput[0] = outFlags; 1348 } 1349 break; 1350 1351 case kAsyncStreamListener_TurnOnNotification: 1352 result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_TurnOnNotification((UserObjectHandle)arguments->scalarInput[0]); 1353 break; 1354 1355 case kAsyncStreamListener_TurnOffNotification: 1356 result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_TurnOffNotification((UserObjectHandle)arguments->scalarInput[0]); 1357 break; 1358 1359 case kSetAsyncRef_BusReset: 1360 { 1361 result = ((IOFireWireUserClient*) targetObject)-> 1362 setAsyncRef_BusReset(arguments->asyncReference, 1363 (mach_vm_address_t)arguments->scalarInput[0], 1364 (io_user_reference_t)arguments->scalarInput[1], 1365 NULL,NULL,NULL,NULL); 1366 } 1367 break; 1368 1369 case kSetAsyncRef_BusResetDone: 1370 { 1371 result = ((IOFireWireUserClient*) targetObject)-> 1372 setAsyncRef_BusResetDone(arguments->asyncReference, 1373 (mach_vm_address_t)arguments->scalarInput[0], 1374 (io_user_reference_t)arguments->scalarInput[1], 1375 NULL,NULL,NULL,NULL); 1376 } 1377 break; 1378 1379 case kSetAsyncRef_Packet: 1380 { 1381 result = ((IOFireWireUserClient*) targetObject)-> 1382 setAsyncRef_Packet(arguments->asyncReference, 1383 (UserObjectHandle)arguments->scalarInput[0], 1384 (mach_vm_address_t)arguments->scalarInput[1], 1385 (io_user_reference_t)arguments->scalarInput[2], 1386 NULL,NULL,NULL); 1387 } 1388 break; 1389 1390 1391 case kSetAsyncRef_SkippedPacket: 1392 { 1393 result = ((IOFireWireUserClient*) targetObject)-> 1394 setAsyncRef_SkippedPacket(arguments->asyncReference, 1395 (UserObjectHandle)arguments->scalarInput[0], 1396 (mach_vm_address_t)arguments->scalarInput[1], 1397 (io_user_reference_t)arguments->scalarInput[2], 1398 NULL,NULL,NULL); 1399 } 1400 break; 1401 1402 case kSetAsyncRef_Read: 1403 { 1404 result = ((IOFireWireUserClient*) targetObject)-> 1405 setAsyncRef_Read(arguments->asyncReference, 1406 (UserObjectHandle)arguments->scalarInput[0], 1407 (mach_vm_address_t)arguments->scalarInput[1], 1408 (io_user_reference_t)arguments->scalarInput[2], 1409 NULL,NULL,NULL); 1410 } 1411 break; 1412 1413 case kCommand_Submit: 1414 { 1415 result = ((IOFireWireUserClient*) targetObject)-> 1416 userAsyncCommand_Submit(arguments->asyncReference, 1417 (CommandSubmitParams*)arguments->structureInput, 1418 (CommandSubmitResult*)arguments->structureOutput, 1419 (IOByteCount) arguments->structureInputSize, 1420 (IOByteCount*) &arguments->structureOutputSize); 1421 } 1422 break; 1423 1424 case kSetAsyncRef_IsochChannelForceStop: 1425 { 1426 result = ((IOFireWireUserClient*) targetObject)-> 1427 setAsyncRef_IsochChannelForceStop(arguments->asyncReference, 1428 (UserObjectHandle)arguments->scalarInput[0]); 1429 } 1430 break; 1431 1432 case kSetAsyncRef_DCLCallProc: 1433 { 1434 result = ((IOFireWireUserClient*) targetObject)-> 1435 setAsyncRef_DCLCallProc(arguments->asyncReference, 1436 (UserObjectHandle)arguments->scalarInput[0]); 1437 } 1438 break; 1439 1440 case kSetAsyncStreamRef_Packet: 1441 { 1442 result = ((IOFireWireUserClient*) targetObject)-> 1443 setAsyncStreamRef_Packet(arguments->asyncReference, 1444 (UserObjectHandle)arguments->scalarInput[0], 1445 (mach_vm_address_t)arguments->scalarInput[1], 1446 (io_user_reference_t)arguments->scalarInput[2], 1447 NULL,NULL,NULL); 1448 } 1449 break; 1450 1451 case kSetAsyncStreamRef_SkippedPacket: 1452 { 1453 result = ((IOFireWireUserClient*) targetObject)-> 1454 setAsyncStreamRef_SkippedPacket(arguments->asyncReference, 1455 (UserObjectHandle)arguments->scalarInput[0], 1456 (mach_vm_address_t)arguments->scalarInput[1], 1457 (io_user_reference_t)arguments->scalarInput[2], 1458 NULL,NULL,NULL); 1459 } 1460 break; 1461 1462 1463 case kIRMAllocation_Allocate: 1464 { 1465 UserObjectHandle outDataHandle; 1466 result = ((IOFireWireUserClient*) targetObject)->irmAllocation_Create(arguments->scalarInput[0],&outDataHandle); 1467 arguments->scalarOutput[0] = (uint64_t) outDataHandle; 1468 } 1469 break; 1470 1471 case kIRMAllocation_AllocateResources: 1472 result = ((IOFireWireUserClient*) targetObject)->irmAllocation_AllocateResources((UserObjectHandle)arguments->scalarInput[0], 1473 arguments->scalarInput[1], 1474 arguments->scalarInput[2]); 1475 break; 1476 1477 1478 case kIRMAllocation_DeallocateResources: 1479 result = ((IOFireWireUserClient*) targetObject)->irmAllocation_DeallocateResources((UserObjectHandle)arguments->scalarInput[0]); 1480 break; 1481 1482 case kIRMAllocation_areResourcesAllocated: 1483 { 1484 UInt8 isochChannel; 1485 UInt32 bandwidthUnits; 1486 result = ((IOFireWireUserClient*) targetObject)->irmAllocation_areResourcesAllocated((UserObjectHandle)arguments->scalarInput[0], &isochChannel , &bandwidthUnits); 1487 arguments->scalarOutput[1] = (uint64_t) isochChannel; 1488 arguments->scalarOutput[2] = (uint64_t) bandwidthUnits; 1489 } 1490 break; 1491 1492 case kIRMAllocation_setDeallocateOnRelease: 1493 ((IOFireWireUserClient*) targetObject)->irmAllocation_setDeallocateOnRelease((UserObjectHandle)arguments->scalarInput[0],arguments->scalarInput[1]); 1494 result = kIOReturnSuccess; 1495 break; 1496 1497 case kIRMAllocation_SetRef: 1498 result = ((IOFireWireUserClient*) targetObject)->irmAllocation_setRef(arguments->asyncReference, 1499 (UserObjectHandle)arguments->scalarInput[0], 1500 arguments->scalarInput[1], 1501 arguments->scalarInput[2]); 1502 break; 1503 1504 case kCommandCreateAsync: 1505 { 1506 result = ((IOFireWireUserClient*) targetObject)-> 1507 createAsyncCommand( arguments->asyncReference, 1508 (CommandSubmitParams*)arguments->structureInput, 1509 (UserObjectHandle*)arguments->structureOutput ); 1510 } 1511 break; 1512 1513 1514 case kVectorCommandCreate: 1515 result = ((IOFireWireUserClient*) targetObject)->createVectorCommand( (UserObjectHandle*)arguments->structureOutput ); 1516 break; 1517 1518 case kVectorCommandSubmit: 1519 result = ((IOFWUserVectorCommand*)targetObject)->submit( arguments->asyncReference, 1520 (mach_vm_address_t)arguments->scalarInput[0], 1521 (io_user_reference_t)arguments->scalarInput[1] ); 1522 break; 1523 1524 case kVectorCommandSetBuffers: 1525 result = ((IOFWUserVectorCommand*)targetObject)->setBuffers( (mach_vm_address_t)arguments->scalarInput[0], 1526 (mach_vm_size_t)arguments->scalarInput[1], 1527 (mach_vm_address_t)arguments->scalarInput[2], 1528 (mach_vm_size_t)arguments->scalarInput[3] ); 1529 break; 1530 1531 case kPHYPacketListenerCreate: 1532 { 1533 UserObjectHandle kernel_ref; 1534 result = ((IOFireWireUserClient*) targetObject)->createPHYPacketListener( (mach_vm_address_t)arguments->scalarInput[0], 1535 &kernel_ref ); 1536 arguments->scalarOutput[0] = (uint64_t)kernel_ref; 1537 } 1538 break; 1539 1540 case kPHYPacketListenerSetPacketCallback: 1541 result = ((IOFWUserPHYPacketListener*)targetObject)->setPacketCallback( arguments->asyncReference, 1542 (mach_vm_address_t)arguments->scalarInput[0], 1543 (io_user_reference_t)arguments->scalarInput[1] ); 1544 break; 1545 1546 case kPHYPacketListenerSetSkippedCallback: 1547 result = ((IOFWUserPHYPacketListener*)targetObject)->setSkippedCallback( arguments->asyncReference, 1548 (mach_vm_address_t)arguments->scalarInput[0], 1549 (io_user_reference_t)arguments->scalarInput[1] ); 1550 break; 1551 1552 case kPHYPacketListenerActivate: 1553 result = ((IOFWUserPHYPacketListener*)targetObject)->activate(); 1554 break; 1555 1556 case kPHYPacketListenerDeactivate: 1557 ((IOFWUserPHYPacketListener*)targetObject)->deactivate(); 1558 result = kIOReturnSuccess; 1559 break; 1560 1561 case kPHYPacketListenerClientCommandIsComplete: 1562 ((IOFWUserPHYPacketListener*)targetObject)->clientCommandIsComplete( (FWClientCommandID)arguments->scalarInput[0] ); 1563 result = kIOReturnSuccess; 1564 break; 1565 1566 default: 1567 // NONE OF THE ABOVE :( 1568 break; 1569 }; 1570 1571 return result; 1572} 1573 1574IOReturn 1575IOFireWireUserClient::registerNotificationPort( 1576 mach_port_t port, 1577 UInt32 /* type */, 1578 UInt32 refCon) 1579{ 1580 fNotificationPort = port ; 1581 fNotificationRefCon = refCon ; 1582 1583 return( kIOReturnUnsupported); 1584} 1585 1586#pragma mark - 1587 1588IOReturn 1589IOFireWireUserClient:: 1590copyUserData ( 1591 mach_vm_address_t userBuffer, 1592 mach_vm_address_t kernBuffer, 1593 mach_vm_size_t bytes ) const 1594{ 1595 if( (userBuffer == NULL) || (kernBuffer == NULL) ) 1596 { 1597 return kIOReturnNoMemory; 1598 } 1599 1600 if( bytes == 0 ) 1601 { 1602 return kIOReturnSuccess; 1603 } 1604 1605 IOMemoryDescriptor * desc = IOMemoryDescriptor::withAddressRange ( userBuffer, bytes, kIODirectionOut, 1606 fTask ) ; 1607 if ( ! desc ) 1608 { 1609 ErrorLog ( "Couldn't create descriptor\n" ) ; 1610 return kIOReturnNoMemory ; 1611 } 1612 1613 // copy user space range list to in kernel list 1614 IOReturn error = desc->prepare () ; 1615 1616 if ( ! error ) 1617 { 1618 if ( bytes != desc->readBytes ( 0, (void*)kernBuffer, bytes ) ) 1619 error = kIOReturnVMError ; 1620 1621 desc->complete() ; 1622 desc->release() ; 1623 } 1624 1625 return error ; 1626} 1627 1628IOReturn 1629IOFireWireUserClient::copyToUserBuffer ( 1630 IOVirtualAddress kernelBuffer, 1631 mach_vm_address_t userBuffer, 1632 IOByteCount bytes, 1633 IOByteCount & bytesCopied ) 1634{ 1635 if( (userBuffer == NULL) || (kernelBuffer == NULL) ) 1636 { 1637 return kIOReturnNoMemory; 1638 } 1639 1640 if( bytes == 0 ) 1641 { 1642 return kIOReturnSuccess; 1643 } 1644 1645 IOMemoryDescriptor * mem = IOMemoryDescriptor::withAddressRange( userBuffer, bytes, kIODirectionIn, fTask ) ; 1646 if ( ! mem ) 1647 return kIOReturnNoMemory ; 1648 1649 IOReturn error = mem->prepare () ; 1650 1651 if ( !error ) 1652 { 1653 bytesCopied = mem->writeBytes ( 0, (void*)kernelBuffer, bytes ) ; 1654 mem->complete() ; 1655 } 1656 1657 mem->release() ; 1658 1659 return error ; 1660} 1661 1662#pragma mark - 1663#pragma mark OPEN/CLOSE 1664 1665IOReturn 1666IOFireWireUserClient::userOpen () 1667{ 1668 IOReturn error = kIOReturnSuccess ; 1669 1670 // do the open... 1671 1672 IOFireWireNub * provider = OSDynamicCast( IOFireWireNub, getOwner() ) ; 1673 if ( ! provider ) 1674 { 1675 ErrorLog( "Couldn't find provider!\b" ) ; 1676 return kIOReturnError ; 1677 } 1678 1679 if ( getOwner()->open( this ) ) 1680 { 1681 IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter(); 1682 error = exporter->addObject( this, NULL, &fSessionRef ); 1683 if( error == kIOReturnSuccess ) 1684 { 1685 fSelfOpenCount = 1 ; 1686 fOpenClient = this ; 1687 } 1688 } 1689 else 1690 { 1691 ErrorLog( "couldn't open provider\n" ) ; 1692 error = kIOReturnExclusiveAccess ; 1693 } 1694 1695 return error ; 1696} 1697 1698IOReturn 1699IOFireWireUserClient::userOpenWithSessionRef ( IOFireWireLib::UserObjectHandle sessionRef ) 1700{ 1701 IOReturn result = kIOReturnSuccess ; 1702 1703 if (getOwner ()->isOpen()) 1704 { 1705 IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter(); 1706 IOService * open_client = (IOService*) exporter->lookupObjectForType( sessionRef, OSTypeID(IOService) ); 1707 IOService * client = open_client; 1708 1709 if (!client) 1710 result = kIOReturnBadArgument ; 1711 else 1712 { 1713 while (client != NULL) 1714 { 1715 if (client == getOwner ()) 1716 { 1717 fOpenClient = open_client ; // sessionRef is the originally passed in user object 1718 1719 if ( fOpenClient == this ) 1720 { 1721 ++fSelfOpenCount ; 1722 } 1723 1724 break ; 1725 } 1726 1727 client = client->getProvider() ; 1728 } 1729 } 1730 1731 if( open_client ) 1732 { 1733 open_client->release(); 1734 open_client = NULL; 1735 } 1736 } 1737 else 1738 result = kIOReturnNotOpen ; 1739 1740 return result ; 1741} 1742 1743IOReturn 1744IOFireWireUserClient::userClose () 1745{ 1746 IOReturn result = kIOReturnSuccess ; 1747 1748 if ( getProvider() == NULL ) 1749 return kIOReturnSuccess ; 1750 1751 if ( fOpenClient == this ) 1752 { 1753 if ( !fOwner->isOpen( this ) ) 1754 { 1755 result = kIOReturnNotOpen ; 1756 } 1757 else 1758 { 1759 if ( fSelfOpenCount > 0 ) 1760 { 1761 if ( --fSelfOpenCount == 0 ) 1762 { 1763 IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter(); 1764 exporter->removeObject( fSessionRef ); 1765 fSessionRef = 0; 1766 fOwner->close(this) ; 1767 fOpenClient = NULL ; 1768 } 1769 } 1770 else 1771 { 1772 return kIOReturnNotOpen ; 1773 } 1774 } 1775 } 1776 1777 return result ; 1778} 1779 1780#pragma mark - 1781#pragma mark GENERAL 1782 1783IOReturn 1784IOFireWireUserClient::readQuad ( const ReadQuadParams* params, UInt32* outVal ) 1785{ 1786 IOReturn err ; 1787 IOFWReadQuadCommand* cmd ; 1788 1789 if ( params->isAbs ) 1790 cmd = this->createReadQuadCommand( params->generation, params->addr, outVal, 1, NULL, NULL ) ; 1791 else 1792 { 1793 if ( (cmd = getOwner ()->createReadQuadCommand( params->addr, outVal, 1, NULL, NULL, params->failOnReset )) ) 1794 cmd->setGeneration( params->generation ) ; 1795 } 1796 1797 if(!cmd) 1798 return kIOReturnNoMemory; 1799 1800 err = cmd->submit(); // We block here until the command finishes 1801 1802 if( !err ) 1803 err = cmd->getStatus(); 1804 1805 cmd->release(); 1806 1807 return err; 1808} 1809 1810IOReturn 1811IOFireWireUserClient::read ( const ReadParams* params, IOByteCount* outBytesTransferred ) 1812{ 1813 IOReturn err ; 1814 IOMemoryDescriptor * mem ; 1815 IOFWReadCommand* cmd ; 1816 1817 *outBytesTransferred = 0 ; 1818 1819 mem = IOMemoryDescriptor::withAddressRange(params->buf, params->size, kIODirectionIn, fTask); 1820 if(!mem) 1821 { 1822 return kIOReturnNoMemory; 1823 } 1824 1825 { 1826 IOReturn error = mem->prepare() ; 1827 if ( kIOReturnSuccess != error ) 1828 { 1829 mem->release() ; 1830 return error ; 1831 } 1832 } 1833 1834 if ( params->isAbs ) 1835 cmd = this->createReadCommand( params->generation, params->addr, mem, NULL, NULL ) ; 1836 else 1837 { 1838 if ( (cmd = getOwner ()->createReadCommand( params->addr, mem, NULL, NULL, params->failOnReset )) ) 1839 cmd->setGeneration(params->generation) ; 1840 } 1841 1842 if(!cmd) 1843 { 1844 mem->complete() ; 1845 mem->release() ; 1846 return kIOReturnNoMemory; 1847 } 1848 1849 err = mem->prepare() ; 1850 1851 if ( err ) 1852 IOLog("%s %u: IOFireWireUserClient::read: prepare failed\n", __FILE__, __LINE__) ; 1853 else 1854 { 1855 err = cmd->submit(); // We block here until the command finishes 1856 mem->complete() ; 1857 } 1858 1859 if( !err ) 1860 err = cmd->getStatus(); 1861 1862 *outBytesTransferred = cmd->getBytesTransferred() ; 1863 1864 cmd->release(); 1865 mem->release(); 1866 1867 return err; 1868} 1869 1870IOReturn 1871IOFireWireUserClient::writeQuad( const WriteQuadParams* params) 1872{ 1873 IOReturn err; 1874 IOFWWriteQuadCommand* cmd ; 1875 1876 if ( params->isAbs ) 1877 cmd = this->createWriteQuadCommand( params->generation, params->addr, (UInt32*) & params->val, 1, NULL, NULL ) ; 1878 else 1879 { 1880 cmd = getOwner ()->createWriteQuadCommand( params->addr, (UInt32*)¶ms->val, 1, NULL, NULL, params->failOnReset ) ; 1881 cmd->setGeneration( params->generation ) ; 1882 } 1883 1884 if(!cmd) 1885 return kIOReturnNoMemory; 1886 1887 1888 err = cmd->submit(); // We block here until the command finishes 1889 1890 if( err ) 1891 err = cmd->getStatus(); 1892 1893 cmd->release(); 1894 1895 return err; 1896} 1897 1898IOReturn 1899IOFireWireUserClient::write( const WriteParams* params, IOByteCount* outBytesTransferred ) 1900{ 1901 IOMemoryDescriptor * mem ; 1902 IOFWWriteCommand* cmd ; 1903 1904 *outBytesTransferred = 0 ; 1905 1906 mem = IOMemoryDescriptor::withAddressRange(params->buf, params->size, kIODirectionOut, fTask); 1907 if(!mem) 1908 { 1909 return kIOReturnNoMemory; 1910 } 1911 1912 { 1913 IOReturn error = mem->prepare() ; 1914 if ( kIOReturnSuccess != error ) 1915 { 1916 mem->release() ; 1917 return error ; 1918 } 1919 } 1920 1921 if ( params->isAbs ) 1922 { 1923 cmd = this->createWriteCommand( params->generation, params->addr, mem, NULL, NULL ) ; 1924 } 1925 else 1926 { 1927 if ( (cmd = getOwner ()->createWriteCommand( params->addr, mem, NULL, NULL, params->failOnReset )) ) 1928 cmd->setGeneration( params->generation ) ; 1929 } 1930 1931 if( !cmd ) 1932 { 1933 mem->complete() ; 1934 mem->release() ; 1935 return kIOReturnNoMemory; 1936 } 1937 1938 IOReturn error ; 1939 error = cmd->submit(); 1940 1941 // We block here until the command finishes 1942 if( !error ) 1943 error = cmd->getStatus(); 1944 1945 if ( !error ) 1946 *outBytesTransferred = cmd->getBytesTransferred() ; 1947 1948 cmd->release(); 1949 1950 mem->complete() ; 1951 mem->release() ; 1952 1953 return error ; 1954} 1955 1956IOReturn 1957IOFireWireUserClient::compareSwap( const CompareSwapParams* params, UInt32* oldVal ) 1958{ 1959 IOReturn err ; 1960 IOFWCompareAndSwapCommand* cmd ; 1961 1962 if ( params->size > 2 ) 1963 return kIOReturnBadArgument ; 1964 1965 if ( params->isAbs ) 1966 { 1967 cmd = this->createCompareAndSwapCommand( params->generation, params->addr, (UInt32*)& params->cmpVal, 1968 (UInt32*)& params->swapVal, params->size, NULL, NULL ) ; 1969 } 1970 else 1971 { 1972 if ( (cmd = getOwner ()->createCompareAndSwapCommand( params->addr, (UInt32*)& params->cmpVal, (UInt32*)& params->swapVal, 1973 params->size, NULL, NULL, params->failOnReset )) ) 1974 { 1975 cmd->setGeneration( params->generation ) ; 1976 } 1977 } 1978 1979 if(!cmd) 1980 return kIOReturnNoMemory; 1981 1982 err = cmd->submit(); 1983 1984 // We block here until the command finishes 1985 if( !err ) 1986 { 1987 cmd->locked(oldVal) ; 1988 err = cmd->getStatus(); 1989// if(kIOReturnSuccess == err && !cmd->locked((UInt32*)oldVal)) 1990// err = kIOReturnCannotLock; 1991 } 1992 1993 cmd->release(); 1994 1995 return err ; 1996} 1997 1998IOReturn 1999IOFireWireUserClient::busReset() 2000{ 2001 FWTrace( kFWTUserClient, kTPUserClientBusReset, (uintptr_t)(getOwner()->getController()->getLink()), fUnsafeResets , 0, 0); 2002 2003 if ( fUnsafeResets ) 2004 return getOwner ()->getController()->getLink()->resetBus(); 2005 2006 return getOwner ()->getController()->resetBus(); 2007} 2008 2009IOReturn 2010IOFireWireUserClient::getGenerationAndNodeID( 2011 UInt32* outGeneration, 2012 UInt32* outNodeID) const 2013{ 2014 UInt16 nodeID ; 2015 2016 getOwner ()->getNodeIDGeneration(*outGeneration, nodeID); 2017 if (!getOwner ()->getController()->checkGeneration(*outGeneration)) 2018 return kIOReturnNotFound ; // nodeID we got was stale... 2019 2020 *outNodeID = (UInt32)nodeID ; 2021 2022 return kIOReturnSuccess ; 2023} 2024 2025IOReturn 2026IOFireWireUserClient::getLocalNodeID( 2027 UInt32* outLocalNodeID) const 2028{ 2029 *outLocalNodeID = (UInt32)(getOwner ()->getController()->getLocalNodeID()) ; 2030 return kIOReturnSuccess ; 2031} 2032 2033IOReturn 2034IOFireWireUserClient::getResetTime( 2035 AbsoluteTime* outResetTime) const 2036{ 2037 *outResetTime = *getOwner ()->getController()->getResetTime() ; 2038 2039 return kIOReturnSuccess ; 2040} 2041 2042IOReturn 2043IOFireWireUserClient::releaseUserObject ( 2044 UserObjectHandle obj ) 2045{ 2046 fExporter->removeObject( obj ) ; 2047 2048 return kIOReturnSuccess ; 2049} 2050 2051#pragma mark - 2052#pragma mark CONVERSION HELPERS 2053 2054IOReturn 2055IOFireWireUserClient::getOSStringData ( 2056 UserObjectHandle stringHandle, 2057 UInt32 stringLen, 2058 mach_vm_address_t stringBuffer, 2059 UInt32 * outTextLength ) 2060{ 2061 *outTextLength = 0 ; 2062 2063 const OSObject * object = fExporter->lookupObject( stringHandle ) ; 2064 if ( !object ) 2065 { 2066 return kIOReturnBadArgument ; 2067 } 2068 2069 OSString * string = OSDynamicCast ( OSString, object ) ; 2070 if ( ! string ) 2071 { 2072 object->release() ; 2073 return kIOReturnBadArgument ; 2074 } 2075 2076 IOByteCount len = min( stringLen, string->getLength() ) ; 2077 IOByteCount outLen = 0; 2078 IOReturn error = copyToUserBuffer ( (IOVirtualAddress) string->getCStringNoCopy(), 2079 stringBuffer, 2080 len, 2081 outLen ) ; 2082 *outTextLength = (UInt32)outLen; 2083 2084 fExporter->removeObject( stringHandle ) ; 2085 string->release() ; 2086 2087 return error ; 2088} 2089 2090IOReturn 2091IOFireWireUserClient::getOSDataData ( 2092 UserObjectHandle dataHandle, 2093 IOByteCount dataLen, 2094 mach_vm_address_t dataBuffer, 2095 IOByteCount* outDataLen) 2096{ 2097 const OSObject * object = fExporter->lookupObject( dataHandle ) ; 2098 if ( !object ) 2099 { 2100 return kIOReturnBadArgument ; 2101 } 2102 2103 OSData * data = OSDynamicCast( OSData, object ) ; 2104 if ( !data ) 2105 { 2106 object->release() ; 2107 return kIOReturnBadArgument ; 2108 } 2109 2110 IOReturn error = copyToUserBuffer ( (IOVirtualAddress) data->getBytesNoCopy(), 2111 dataBuffer, 2112 min( data->getLength(), dataLen ), 2113 *outDataLen ) ; 2114 fExporter->removeObject( dataHandle ) ; 2115 2116 object->release() ; // this is retained when we call lookupObject; "I must release you" 2117 2118 return error ; 2119} 2120 2121#pragma mark - 2122#pragma mark LOCAL CONFIG DIRECTORY 2123 2124// Config Directory methods 2125 2126IOReturn 2127IOFireWireUserClient::localConfigDirectory_Create ( UserObjectHandle* outDir ) 2128{ 2129 IOLocalConfigDirectory * dir = IOLocalConfigDirectory::create () ; 2130 2131 if ( ! dir ) 2132 { 2133 DebugLog( "IOLocalConfigDirectory::create returned NULL\n" ) ; 2134 return kIOReturnNoMemory ; 2135 } 2136 2137 IOReturn error = fExporter->addObject ( dir, (IOFWUserObjectExporter::CleanupFunction)&IOLocalConfigDirectory::exporterCleanup, outDir ) ; 2138 2139 dir->release() ; 2140 2141 return error ; 2142} 2143 2144IOReturn 2145IOFireWireUserClient::localConfigDirectory_addEntry_Buffer ( 2146 UserObjectHandle dirHandle, 2147 int key, 2148 char * buffer, 2149 UInt32 kr_size, 2150 const char * descCString, 2151 UInt32 descLen ) const 2152{ 2153 2154 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2155 if ( !object ) 2156 { 2157 return kIOReturnBadArgument ; 2158 } 2159 2160 IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ; 2161 if ( ! dir ) 2162 { 2163 object->release() ; 2164 return kIOReturnBadArgument ; 2165 } 2166 2167 IOReturn error = kIOReturnSuccess ; 2168 OSData * data = OSData::withCapacity( kr_size ) ; 2169 if ( !data ) 2170 { 2171 error = kIOReturnNoMemory ; 2172 } 2173 else 2174 { 2175 data->appendBytes( NULL, kr_size ); // force internal buffer allocation 2176 copyUserData( (IOVirtualAddress)buffer, (IOVirtualAddress)data->getBytesNoCopy(), kr_size ) ; 2177 2178 OSString * desc = NULL ; 2179 if ( descCString && (descLen < 1024) ) 2180 { 2181 char * cStr = new char[ descLen ]; 2182 if ( cStr ) 2183 { 2184 copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ; 2185 2186 cStr[ descLen-1 ] = 0 ; 2187 desc = OSString::withCString( cStr ) ; 2188 2189 delete [] cStr; 2190 } 2191 } 2192 2193 error = dir->addEntry ( key, data, desc ) ; 2194 2195 data->release() ; 2196 } 2197 2198 dir->release() ; 2199 2200 return error ; 2201} 2202 2203IOReturn 2204IOFireWireUserClient::localConfigDirectory_addEntry_UInt32 ( 2205 UserObjectHandle dirHandle, 2206 int key, 2207 UInt32 value, 2208 const char * descCString, 2209 UInt32 descLen ) const 2210{ 2211 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2212 if ( !object ) 2213 { 2214 return kIOReturnBadArgument ; 2215 } 2216 2217 IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ; 2218 if ( ! dir ) 2219 { 2220 object->release() ; 2221 return kIOReturnBadArgument ; 2222 } 2223 2224 OSString * desc = NULL ; 2225 if ( descCString && (descLen < 1024) ) 2226 { 2227 char * cStr = new char[ descLen ]; 2228 if ( cStr ) 2229 { 2230 copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ; 2231 2232 cStr[ descLen-1 ] = 0 ; 2233 desc = OSString::withCString( cStr ) ; 2234 2235 delete [] cStr; 2236 } 2237 } 2238 2239 IOReturn error = dir->addEntry(key, value, desc) ; 2240 2241 dir->release() ; 2242 2243 return error ; 2244} 2245 2246IOReturn 2247IOFireWireUserClient::localConfigDirectory_addEntry_FWAddr ( 2248 UserObjectHandle dirHandle, 2249 int key, 2250 const char * descCString, 2251 UInt32 descLen, 2252 FWAddress * value ) const 2253{ 2254 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2255 if ( !object ) 2256 { 2257 return kIOReturnBadArgument ; 2258 } 2259 2260 IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ; 2261 if ( ! dir ) 2262 { 2263 object->release() ; 2264 return kIOReturnBadArgument ; 2265 } 2266 2267 OSString * desc = NULL ; 2268 if ( descCString && (descLen < 1024) ) 2269 { 2270 char * cStr = new char[ descLen ]; 2271 if ( cStr ) 2272 { 2273 copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ; 2274 2275 cStr[ descLen-1 ] = 0 ; 2276 desc = OSString::withCString( cStr ) ; 2277 2278 delete [] cStr; 2279 } 2280 } 2281 2282 IOReturn error = dir->addEntry( key, *value, desc ) ; 2283 2284 dir->release() ; 2285 2286 return error ; 2287} 2288 2289IOReturn 2290IOFireWireUserClient::localConfigDirectory_addEntry_UnitDir ( 2291 UserObjectHandle dirHandle, 2292 int key, 2293 UserObjectHandle valueHandle, 2294 const char * descCString, 2295 UInt32 descLen ) const 2296{ 2297 IOLocalConfigDirectory * dir ; 2298 { 2299 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2300 if ( !object ) 2301 { 2302 return kIOReturnBadArgument ; 2303 } 2304 2305 dir = OSDynamicCast( IOLocalConfigDirectory, object ) ; 2306 if ( ! dir ) 2307 { 2308 object->release() ; 2309 return kIOReturnBadArgument ; 2310 } 2311 } 2312 2313 IOReturn error ; 2314 IOLocalConfigDirectory * value ; 2315 2316 { 2317 const OSObject * object = fExporter->lookupObject( valueHandle ) ; 2318 if ( !object ) 2319 { 2320 return kIOReturnBadArgument ; 2321 } 2322 2323 value = OSDynamicCast( IOLocalConfigDirectory, object ) ; 2324 2325 if ( ! value ) 2326 { 2327 object->release() ; 2328 error = kIOReturnBadArgument ; 2329 } 2330 else 2331 { 2332 OSString * desc = NULL ; 2333 2334 if ( descCString && (descLen < 1024) ) 2335 { 2336 char * cStr = new char[ descLen ]; 2337 if ( cStr ) 2338 { 2339 copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ; 2340 2341 cStr[ descLen-1 ] = 0 ; 2342 desc = OSString::withCString( cStr ) ; 2343 2344 delete [] cStr; 2345 } 2346 } 2347 2348 error = dir->addEntry( key, value, desc ) ; 2349 2350 value->release() ; 2351 } 2352 } 2353 2354 dir->release() ; // lookupObject retains the object 2355 2356 return error ; 2357} 2358 2359IOReturn 2360IOFireWireUserClient::localConfigDirectory_Publish ( UserObjectHandle dirHandle ) const 2361{ 2362 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2363 if ( !object ) 2364 { 2365 return kIOReturnBadArgument ; 2366 } 2367 2368 IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ; 2369 if ( ! dir ) 2370 { 2371 object->release() ; 2372 return kIOReturnBadArgument ; 2373 } 2374 2375 IOReturn error = getOwner ()->getController()->AddUnitDirectory( dir ) ; 2376 2377 dir->release() ; // lookupObject retains result; "I must release you" 2378 2379 return error ; 2380} 2381 2382IOReturn 2383IOFireWireUserClient::localConfigDirectory_Unpublish ( UserObjectHandle dirHandle ) const 2384{ 2385 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2386 if ( !object ) 2387 { 2388 return kIOReturnBadArgument ; 2389 } 2390 2391 IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ; 2392 if ( ! dir ) 2393 { 2394 object->release() ; 2395 return kIOReturnBadArgument ; 2396 } 2397 2398 IOReturn error = getOwner ()->getBus()->RemoveUnitDirectory ( dir ) ; 2399 2400 dir->release() ; // lookupObject retains result; "I must release you" 2401 2402 return error ; 2403} 2404 2405#pragma mark - 2406#pragma mark ADDRESS SPACES 2407 2408// 2409// Address Space methods 2410// 2411 2412IOReturn 2413IOFireWireUserClient::addressSpace_Create ( 2414 AddressSpaceCreateParams * params, 2415 UserObjectHandle * outAddressSpaceHandle ) 2416{ 2417 IOFWUserPseudoAddressSpace * addressSpace = OSTypeAlloc( IOFWUserPseudoAddressSpace ); 2418 2419 if ( addressSpace && 2420 ( params->isInitialUnits ? 2421 !addressSpace->initFixed( this, params ) : !addressSpace->initPseudo( this, params ) ) ) 2422 { 2423 return kIOReturnNoMemory ; 2424 } 2425 2426 IOReturn error = addressSpace->activate() ; 2427 2428 if ( !error ) 2429 error = fExporter->addObject ( addressSpace, 2430 &IOFWUserPseudoAddressSpace::exporterCleanup, 2431 outAddressSpaceHandle ) ; // nnn needs cleanup function? 2432 2433 if ( error ) 2434 addressSpace->deactivate() ; 2435 2436 addressSpace->release() ; 2437 2438 return error ; 2439} 2440 2441IOReturn 2442IOFireWireUserClient::addressSpace_GetInfo ( 2443 UserObjectHandle addressSpaceHandle, 2444 AddressSpaceInfo * outInfo ) 2445{ 2446 const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ; 2447 if ( !object ) 2448 { 2449 return kIOReturnBadArgument ; 2450 } 2451 2452 IOFWUserPseudoAddressSpace * me = OSDynamicCast( IOFWUserPseudoAddressSpace, object ) ; 2453 if (!me) 2454 { 2455 object->release() ; 2456 return kIOReturnBadArgument ; 2457 } 2458 2459 outInfo->address = me->getBase() ; 2460 2461 me->release() ; 2462 2463 return kIOReturnSuccess ; 2464} 2465 2466IOReturn 2467IOFireWireUserClient::addressSpace_ClientCommandIsComplete ( 2468 UserObjectHandle addressSpaceHandle, 2469 FWClientCommandID inCommandID, 2470 IOReturn inResult) 2471{ 2472 const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ; 2473 if ( !object ) 2474 { 2475 return kIOReturnBadArgument ; 2476 } 2477 2478 IOReturn result = kIOReturnSuccess ; 2479 IOFWUserPseudoAddressSpace * me = OSDynamicCast( IOFWUserPseudoAddressSpace, object ) ; 2480 if (!me) 2481 { 2482 object->release() ; 2483 return kIOReturnBadArgument ; 2484 } 2485 2486 me->clientCommandIsComplete ( inCommandID, inResult ) ; 2487 me->release() ; 2488 2489 return result ; 2490} 2491 2492IOReturn 2493IOFireWireUserClient::setAsyncRef_Packet ( 2494 OSAsyncReference64 asyncRef, 2495 UserObjectHandle addressSpaceHandle, 2496 mach_vm_address_t inCallback, 2497 io_user_reference_t inUserRefCon, 2498 void*, 2499 void*, 2500 void*) 2501{ 2502 const OSObject * object = fExporter->lookupObject ( addressSpaceHandle ) ; 2503 if ( !object ) 2504 { 2505 return kIOReturnBadArgument ; 2506 } 2507 2508 IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ; 2509 if ( ! me ) 2510 { 2511 object->release() ; 2512 return kIOReturnBadArgument ; 2513 } 2514 2515 if ( inCallback ) 2516 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ; 2517 else 2518 asyncRef[0] = 0 ; 2519 2520 me->setAsyncRef_Packet(asyncRef) ; 2521 me->release() ; 2522 2523 return kIOReturnSuccess ; 2524} 2525 2526IOReturn 2527IOFireWireUserClient::setAsyncRef_SkippedPacket( 2528 OSAsyncReference64 asyncRef, 2529 UserObjectHandle inAddrSpaceRef, 2530 mach_vm_address_t inCallback, 2531 io_user_reference_t inUserRefCon, 2532 void*, 2533 void*, 2534 void*) 2535{ 2536 const OSObject * object = fExporter->lookupObject ( inAddrSpaceRef ) ; 2537 if ( !object ) 2538 { 2539 return kIOReturnBadArgument ; 2540 } 2541 2542 IOReturn result = kIOReturnSuccess ; 2543 IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ; 2544 2545 if ( !me ) 2546 { 2547 object->release() ; 2548 result = kIOReturnBadArgument ; 2549 } 2550 2551 if ( kIOReturnSuccess == result ) 2552 { 2553 if (inCallback) 2554 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t) inCallback, (io_user_reference_t)inUserRefCon ) ; 2555 else 2556 asyncRef[0] = 0 ; 2557 2558 me->setAsyncRef_SkippedPacket(asyncRef) ; 2559 } 2560 2561 me->release(); 2562 2563 return result ; 2564} 2565 2566IOReturn 2567IOFireWireUserClient::setAsyncRef_Read( 2568 OSAsyncReference64 asyncRef, 2569 UserObjectHandle inAddrSpaceRef, 2570 mach_vm_address_t inCallback, 2571 io_user_reference_t inUserRefCon, 2572 void*, 2573 void*, 2574 void*) 2575{ 2576 const OSObject * object = fExporter->lookupObject ( inAddrSpaceRef ) ; 2577 if ( !object ) 2578 { 2579 return kIOReturnBadArgument ; 2580 } 2581 2582 IOReturn result = kIOReturnSuccess ; 2583 IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ; 2584 2585 if ( !me ) 2586 { 2587 object->release() ; 2588 result = kIOReturnBadArgument ; 2589 } 2590 2591 if ( kIOReturnSuccess == result ) 2592 { 2593 if (inCallback) 2594 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ; 2595 else 2596 asyncRef[0] = 0 ; 2597 2598 me->setAsyncRef_Read(asyncRef) ; 2599 } 2600 2601 me->release(); 2602 2603 return result ; 2604} 2605 2606IOReturn 2607IOFireWireUserClient::setAsyncRef_BusReset( 2608 OSAsyncReference64 asyncRef, 2609 mach_vm_address_t inCallback, 2610 io_user_reference_t inRefCon, 2611 void*, 2612 void*, 2613 void*, 2614 void*) 2615{ 2616 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)inCallback, (io_user_reference_t)inRefCon ) ; 2617 2618 bcopy(asyncRef, fBusResetAsyncNotificationRef, sizeof(OSAsyncReference64)) ; 2619 2620 return kIOReturnSuccess ; 2621} 2622 2623IOReturn 2624IOFireWireUserClient::setAsyncRef_BusResetDone( 2625 OSAsyncReference64 inAsyncRef, 2626 mach_vm_address_t inCallback, 2627 io_user_reference_t inRefCon, 2628 void*, 2629 void*, 2630 void*, 2631 void*) 2632{ 2633 super::setAsyncReference64 ( inAsyncRef, (mach_port_t) inAsyncRef[0], inCallback, (io_user_reference_t)inRefCon ) ; 2634 2635 bcopy(inAsyncRef, fBusResetDoneAsyncNotificationRef, sizeof(OSAsyncReference64)) ; 2636 2637 return kIOReturnSuccess ; 2638} 2639 2640#pragma mark - 2641#pragma mark PHYSICAL ADDRESS SPACES 2642// 2643// --- physical addr spaces ---------- 2644// 2645 2646IOReturn 2647IOFireWireUserClient::physicalAddressSpace_Create ( 2648// PhysicalAddressSpaceCreateParams * params, 2649 mach_vm_size_t size, 2650 mach_vm_address_t backingStore, 2651 UInt32 flags, 2652 UserObjectHandle * outAddressSpaceHandle ) 2653{ 2654 IOMemoryDescriptor* mem = IOMemoryDescriptor::withAddressRange( backingStore, size, kIODirectionOutIn, fTask ) ; 2655 if ( ! mem ) 2656 { 2657 DebugLog("couldn't get memory descriptor for physical address space memory\n") ; 2658 return kIOReturnNoMemory ; 2659 } 2660 2661 IOReturn error = mem->prepare( kIODirectionPrepareToPhys32 ); 2662 if ( error ) 2663 { 2664 DebugLog("couldn't prepare address space memory descriptor\n") ; 2665 mem->release() ; 2666 return error ; 2667 } 2668 2669 IOFWUserPhysicalAddressSpace * addrSpace = OSTypeAlloc( IOFWUserPhysicalAddressSpace ); 2670 if ( addrSpace && !addrSpace->initWithDesc( getOwner()->getController(), mem ) ) 2671 { 2672 addrSpace->release() ; 2673 addrSpace = NULL ; 2674 } 2675 2676 if ( ! addrSpace ) 2677 { 2678 error = kIOReturnNoMemory ; 2679 } 2680 else 2681 { 2682 error = addrSpace->activate() ; 2683 2684 if ( ! error ) 2685 error = fExporter->addObject( addrSpace, 2686 &IOFWUserPhysicalAddressSpace::exporterCleanup, 2687 outAddressSpaceHandle ); 2688 2689 addrSpace->release () ; // fExporter will retain this 2690 } 2691 2692 mem->release() ; // address space will retain this if it needs it.. in any case 2693 // we're done with it. 2694 2695 return error ; 2696 2697} 2698 2699IOReturn 2700IOFireWireUserClient::physicalAddressSpace_GetSegments ( 2701 UserObjectHandle addressSpaceHandle, 2702 UInt32 inSegmentCount, 2703 mach_vm_address_t outSegments, 2704 UInt32* outSegmentCount) 2705{ 2706 const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ; 2707 if ( !object ) 2708 { 2709 return kIOReturnBadArgument ; 2710 } 2711 2712 IOFWUserPhysicalAddressSpace* addressSpace = OSDynamicCast( IOFWUserPhysicalAddressSpace, object ) ; 2713 2714 if ( ! addressSpace ) 2715 { 2716 object->release() ; 2717 return kIOReturnBadArgument ; 2718 } 2719 2720 UInt32 segmentCount ; 2721 IOReturn error = addressSpace->getSegmentCount( &segmentCount ) ; 2722 if ( error == kIOReturnSuccess ) 2723 { 2724 segmentCount = min( segmentCount, inSegmentCount ) ; 2725 2726 FWPhysicalSegment32 * segments = new FWPhysicalSegment32[ segmentCount ] ; 2727 2728 if ( !segments ) 2729 { 2730 error = kIOReturnNoMemory ; 2731 } 2732 2733 if ( !error ) 2734 { 2735 error = addressSpace->getSegments( & segmentCount, segments ) ; 2736 } 2737 2738 if ( ! error ) 2739 { 2740 IOByteCount bytesCopied ; 2741 error = copyToUserBuffer( (IOVirtualAddress)segments, outSegments, sizeof( FWPhysicalSegment32 ) * segmentCount, bytesCopied ) ; 2742 2743 *outSegmentCount = bytesCopied / sizeof( FWPhysicalSegment32 ) ; 2744 } 2745 2746 delete[] segments ; 2747 } 2748 2749 addressSpace->release() ; // retained by call to lookupObject() 2750 2751 return error ; 2752} 2753 2754#pragma mark 2755#pragma mark CONFIG DIRECTORY 2756 2757IOReturn 2758IOFireWireUserClient::configDirectory_Create ( UserObjectHandle * outDirRef ) 2759{ 2760 IOConfigDirectory * configDir ; 2761 IOReturn error = getOwner ()->getConfigDirectoryRef ( configDir ); 2762 2763 if ( error ) 2764 return error ; 2765 2766 if ( !configDir ) 2767 error = kIOReturnNoMemory ; 2768 else 2769 { 2770 error = fExporter->addObject ( configDir, NULL, outDirRef ) ; 2771 configDir->release () ; 2772 } 2773 2774 return error ; 2775} 2776 2777IOReturn 2778IOFireWireUserClient::configDirectory_GetKeyType ( 2779 UserObjectHandle dirHandle, 2780 int key, 2781 IOConfigKeyType * outType) const 2782{ 2783 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2784 if ( !object ) 2785 { 2786 return kIOReturnBadArgument ; 2787 } 2788 2789 IOConfigDirectory * dir = OSDynamicCast( IOConfigDirectory, object ) ; 2790 if ( !dir ) 2791 { 2792 object->release() ; 2793 return kIOReturnBadArgument ; 2794 } 2795 2796 IOReturn error = dir->getKeyType(key, *outType) ; 2797 2798 dir->release() ; 2799 2800 return error ; 2801} 2802 2803IOReturn 2804IOFireWireUserClient::configDirectory_GetKeyValue_UInt32 ( 2805 UserObjectHandle dirHandle, 2806 int key, 2807 UInt32 wantText, 2808 UInt32 * outValue, 2809 UserObjectHandle * outTextHandle, 2810 UInt32 * outTextLength ) const 2811{ 2812 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2813 if ( !object ) 2814 { 2815 return kIOReturnBadArgument ; 2816 } 2817 2818 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 2819 if ( ! dir ) 2820 { 2821 object->release() ; 2822 return kIOReturnBadArgument ; 2823 } 2824 2825 OSString * outString = NULL ; 2826 IOReturn error = dir->getKeyValue( key, *outValue, ((bool)wantText) ? & outString : NULL ) ; 2827 2828 if ( outString && !error ) 2829 { 2830 error = fExporter->addObject( outString, NULL, outTextHandle ) ; 2831 2832 outString->release () ; 2833 2834 if ( ! error ) 2835 *outTextLength = outString->getLength() ; 2836 } 2837 2838 dir->release() ; 2839 2840 return error ; 2841} 2842 2843IOReturn 2844IOFireWireUserClient::configDirectory_GetKeyValue_Data ( 2845 UserObjectHandle dirHandle, 2846 int key, 2847 UInt32 wantText, 2848 GetKeyValueDataResults * results ) const 2849{ 2850 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2851 if ( !object ) 2852 { 2853 return kIOReturnBadArgument ; 2854 } 2855 2856 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 2857 if ( ! dir ) 2858 { 2859 object->release() ; 2860 return kIOReturnBadArgument ; 2861 } 2862 2863 OSData * outData = NULL ; 2864 OSString * outText = NULL ; 2865 IOReturn error = dir->getKeyValue ( key, outData, ((bool)wantText) ? & outText : NULL ) ; 2866 2867 if ( outText ) 2868 { 2869 if ( ! error ) 2870 { 2871 error = fExporter->addObject( outText, NULL, &results->text ) ; 2872 results->textLength = outText->getLength() ; 2873 } 2874 2875 outText->release() ; 2876 } 2877 2878 if ( outData ) 2879 { 2880 if ( ! error ) 2881 { 2882 error = fExporter->addObject( outData, NULL, &results->data ) ; 2883 results->dataLength = outData->getLength() ; 2884 } 2885 2886 outData->release() ; 2887 } 2888 2889 dir->release() ; 2890 2891 return error ; 2892} 2893 2894IOReturn 2895IOFireWireUserClient::configDirectory_GetKeyValue_ConfigDirectory( 2896 UserObjectHandle dirHandle, 2897 int key, 2898 UInt32 wantText, 2899 UserObjectHandle * outDirHandle, 2900 UserObjectHandle * outTextHandle, 2901 UInt32 * outTextLength ) const 2902{ 2903 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2904 if ( !object ) 2905 { 2906 return kIOReturnBadArgument ; 2907 } 2908 2909 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 2910 if ( ! dir ) 2911 { 2912 object->release() ; 2913 return kIOReturnBadArgument ; 2914 } 2915 2916 OSString * outText = NULL ; 2917 IOConfigDirectory * outDir = NULL ; 2918 IOReturn error = dir->getKeyValue ( key, outDir, ((bool)wantText) ? & outText : NULL ) ; 2919 2920 if ( outText ) 2921 { 2922 if ( ! error ) 2923 { 2924 *outTextLength = outText->getLength() ; 2925 error = fExporter->addObject( outText, NULL, outTextHandle ) ; 2926 } 2927 2928 outText->release() ; 2929 } 2930 2931 if ( outDir ) 2932 { 2933 if ( ! error ) 2934 error = fExporter->addObject( outDir, NULL, outDirHandle ) ; 2935 2936 outDir->release() ; 2937 } 2938 2939 dir->release() ; 2940 2941 return error ; 2942} 2943 2944IOReturn 2945IOFireWireUserClient::configDirectory_GetKeyOffset_FWAddress ( 2946 UserObjectHandle dirHandle, 2947 int key, 2948 UInt32 wantText, 2949 GetKeyOffsetResults * results ) const 2950{ 2951 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2952 if ( !object ) 2953 { 2954 return kIOReturnBadArgument ; 2955 } 2956 2957 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 2958 if ( ! dir ) 2959 { 2960 object->release() ; 2961 return kIOReturnBadArgument ; 2962 } 2963 2964 OSString * outText = NULL ; 2965 IOReturn error = dir->getKeyOffset ( key, results->address, ((bool)wantText) ? & outText : NULL) ; 2966 2967 if ( outText ) 2968 { 2969 if ( ! error ) 2970 { 2971 results->length = outText->getLength() ; 2972 error = fExporter->addObject( outText, NULL, &results->text ) ; 2973 } 2974 2975 outText->release() ; 2976 } 2977 2978 dir->release() ; 2979 2980 return error ; 2981} 2982 2983IOReturn 2984IOFireWireUserClient::configDirectory_GetIndexType ( 2985 UserObjectHandle dirHandle, 2986 int index, 2987 IOConfigKeyType* outType ) const 2988{ 2989 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 2990 if ( !object ) 2991 { 2992 return kIOReturnBadArgument ; 2993 } 2994 2995 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 2996 if ( ! dir ) 2997 { 2998 object->release() ; 2999 return kIOReturnBadArgument ; 3000 } 3001 3002 IOReturn error = dir->getIndexType(index, *outType) ; 3003 3004 dir->release() ; 3005 3006 return error ; 3007} 3008 3009IOReturn 3010IOFireWireUserClient::configDirectory_GetIndexKey ( 3011 UserObjectHandle dirHandle, 3012 int index, 3013 int * outKey ) const 3014{ 3015 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3016 if ( !object ) 3017 { 3018 return kIOReturnBadArgument ; 3019 } 3020 3021 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3022 if ( ! dir ) 3023 { 3024 object->release() ; 3025 return kIOReturnBadArgument ; 3026 } 3027 3028 IOReturn error = dir->getIndexKey(index, *outKey) ; 3029 3030 dir->release() ; 3031 3032 return error ; 3033} 3034 3035IOReturn 3036IOFireWireUserClient::configDirectory_GetIndexValue_UInt32 ( 3037 UserObjectHandle dirHandle, 3038 int index, 3039 UInt32* outKey ) const 3040{ 3041 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3042 if ( !object ) 3043 { 3044 return kIOReturnBadArgument ; 3045 } 3046 3047 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3048 if ( ! dir ) 3049 { 3050 object->release() ; 3051 return kIOReturnBadArgument ; 3052 } 3053 3054 IOReturn error = dir->getIndexValue(index, *outKey) ; 3055 3056 dir->release() ; 3057 3058 return error ; 3059} 3060 3061IOReturn 3062IOFireWireUserClient::configDirectory_GetIndexValue_Data ( 3063 UserObjectHandle dirHandle, 3064 int index, 3065 UserObjectHandle * outDataHandle, 3066 IOByteCount * outDataLen ) const 3067{ 3068 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3069 if ( !object ) 3070 { 3071 return kIOReturnBadArgument ; 3072 } 3073 3074 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3075 if ( ! dir ) 3076 { 3077 object->release() ; 3078 return kIOReturnBadArgument ; 3079 } 3080 3081 OSData * outData = NULL ; 3082 IOReturn error = dir->getIndexValue( index, outData ) ; 3083 3084 if ( !error && outData ) 3085 { 3086 error = fExporter->addObject( outData, NULL, outDataHandle ) ; 3087 *outDataLen = outData->getLength() ; 3088 3089 outData->release() ; 3090 } 3091 3092 dir->release() ; 3093 3094 return error ; 3095} 3096 3097IOReturn 3098IOFireWireUserClient::configDirectory_GetIndexValue_String ( 3099 UserObjectHandle dirHandle, 3100 int index, 3101 UserObjectHandle * outTextHandle, 3102 UInt32 * outTextLength ) const 3103{ 3104 InfoLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String, index=%d, outTextHandle=%p\n", this ) ; 3105 3106 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3107 if ( !object ) 3108 { 3109 DebugLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String() -- dir handle is invalid\n", this ) ; 3110 return kIOReturnBadArgument ; 3111 } 3112 3113 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3114 if ( ! dir ) 3115 { 3116 DebugLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String() -- dir handle is not a config directory object!\n", this ) ; 3117 3118 object->release() ; 3119 return kIOReturnBadArgument ; 3120 } 3121 3122 OSString * outText = NULL ; 3123 IOReturn error = dir->getIndexValue( index, outText ) ; 3124 3125 InfoLog("a. IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String error=%x\n", this, error ) ; 3126 3127 if ( !error && outText ) 3128 { 3129 *outTextLength = outText->getLength() ; 3130 3131 error = fExporter->addObject( outText, NULL, outTextHandle ) ; 3132 3133 outText->release() ; 3134 } 3135 3136 dir->release() ; 3137 3138 return error ; 3139} 3140 3141IOReturn 3142IOFireWireUserClient::configDirectory_GetIndexValue_ConfigDirectory ( 3143 UserObjectHandle dirHandle, 3144 int index, 3145 UserObjectHandle * outDirHandle ) const 3146{ 3147 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3148 if ( !object ) 3149 { 3150 return kIOReturnBadArgument ; 3151 } 3152 3153 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3154 if ( ! dir ) 3155 { 3156 object->release() ; 3157 return kIOReturnBadArgument ; 3158 } 3159 3160 IOConfigDirectory * outDir = NULL ; 3161 IOReturn error = dir->getIndexValue( index, outDir ) ; 3162 3163 if ( ! error && outDir ) 3164 { 3165 error = fExporter->addObject ( outDir, NULL, outDirHandle ) ; 3166 outDir->release() ; 3167 } 3168 3169 dir->release() ; 3170 3171 return error ; 3172} 3173 3174IOReturn 3175IOFireWireUserClient::configDirectory_GetIndexOffset_FWAddress ( 3176 UserObjectHandle dirHandle, 3177 int index, 3178 FWAddress * outAddress ) const 3179{ 3180 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3181 if ( !object ) 3182 { 3183 return kIOReturnBadArgument ; 3184 } 3185 3186 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3187 if ( ! dir ) 3188 { 3189 object->release() ; 3190 return kIOReturnBadArgument ; 3191 } 3192 3193 IOReturn result = dir->getIndexOffset( index, *outAddress ) ; 3194 3195 dir->release() ; 3196 3197 return result ; 3198} 3199 3200IOReturn 3201IOFireWireUserClient::configDirectory_GetIndexOffset_UInt32 ( 3202 UserObjectHandle dirHandle, 3203 int index, 3204 UInt32* outValue) const 3205{ 3206 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3207 if ( !object ) 3208 { 3209 return kIOReturnBadArgument ; 3210 } 3211 3212 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3213 if ( ! dir ) 3214 { 3215 object->release() ; 3216 return kIOReturnBadArgument ; 3217 } 3218 3219 IOReturn error = dir->getIndexOffset(index, *outValue) ; 3220 3221 dir->release() ; 3222 3223 return error ; 3224} 3225 3226IOReturn 3227IOFireWireUserClient::configDirectory_GetIndexEntry ( 3228 UserObjectHandle dirHandle, 3229 int index, 3230 UInt32* outValue) const 3231{ 3232 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3233 if ( !object ) 3234 { 3235 return kIOReturnBadArgument ; 3236 } 3237 3238 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3239 if ( ! dir ) 3240 { 3241 object->release() ; 3242 return kIOReturnBadArgument ; 3243 } 3244 3245 IOReturn error = dir->getIndexEntry(index, *outValue) ; 3246 3247 dir->release() ; 3248 3249 return error ; 3250} 3251 3252IOReturn 3253IOFireWireUserClient::configDirectory_GetSubdirectories ( 3254 UserObjectHandle dirHandle, 3255 UserObjectHandle* outIteratorHandle ) const 3256{ 3257 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3258 if ( !object ) 3259 { 3260 return kIOReturnBadArgument ; 3261 } 3262 3263 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3264 if ( ! dir ) 3265 { 3266 object->release() ; 3267 return kIOReturnBadArgument ; 3268 } 3269 3270 OSIterator * outIterator = NULL ; 3271 IOReturn error = dir->getSubdirectories( outIterator ) ; 3272 3273 if ( outIterator ) 3274 { 3275 if ( ! error ) 3276 error = fExporter->addObject( outIterator, NULL, outIteratorHandle ) ; 3277 3278 outIterator->release () ; 3279 } 3280 3281 dir->release() ; 3282 3283 return error ; 3284} 3285 3286IOReturn 3287IOFireWireUserClient::configDirectory_GetKeySubdirectories ( 3288 UserObjectHandle dirHandle , 3289 int key, 3290 UserObjectHandle* outIteratorHandle ) const 3291{ 3292 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3293 if ( !object ) 3294 { 3295 return kIOReturnBadArgument ; 3296 } 3297 3298 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3299 if ( ! dir ) 3300 { 3301 object->release() ; 3302 return kIOReturnBadArgument ; 3303 } 3304 3305 OSIterator * outIterator = NULL ; 3306 IOReturn error = dir->getKeySubdirectories( key, outIterator ) ; 3307 3308 if ( outIterator ) 3309 { 3310 if ( ! error ) 3311 error = fExporter->addObject( outIterator, NULL, outIteratorHandle ) ; 3312 3313 outIterator->release() ; 3314 } 3315 3316 dir->release() ; 3317 3318 return error ; 3319} 3320 3321IOReturn 3322IOFireWireUserClient::configDirectory_GetType ( 3323 UserObjectHandle dirHandle, 3324 int* outType) const 3325{ 3326 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3327 if ( !object ) 3328 { 3329 return kIOReturnBadArgument ; 3330 } 3331 3332 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3333 if ( ! dir ) 3334 { 3335 object->release() ; 3336 return kIOReturnBadArgument ; 3337 } 3338 3339 *outType = dir->getType(); 3340 3341 dir->release() ; 3342 3343 return kIOReturnSuccess ; 3344} 3345 3346IOReturn 3347IOFireWireUserClient::configDirectory_GetNumEntries ( 3348 UserObjectHandle dirHandle, 3349 int* outNumEntries) const 3350{ 3351 const OSObject * object = fExporter->lookupObject( dirHandle ) ; 3352 if ( !object ) 3353 { 3354 return kIOReturnBadArgument ; 3355 } 3356 3357 IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ; 3358 if ( ! dir ) 3359 { 3360 object->release() ; 3361 return kIOReturnBadArgument ; 3362 } 3363 3364 *outNumEntries = dir->getNumEntries() ; 3365 dir->release() ; 3366 3367 return kIOReturnSuccess ; 3368} 3369 3370#pragma mark - 3371#pragma mark LOCAL ISOCH PORT 3372 3373IOReturn 3374IOFireWireUserClient::localIsochPort_GetSupported( 3375 UserObjectHandle portHandle, 3376 IOFWSpeed* outMaxSpeed, 3377 UInt32* outChanSupportedHi, 3378 UInt32* outChanSupportedLo) const 3379{ 3380 const OSObject * object = fExporter->lookupObject( portHandle ) ; 3381 if ( !object ) 3382 { 3383 return kIOReturnBadArgument ; 3384 } 3385 3386 IOFWUserLocalIsochPort * port = OSDynamicCast ( IOFWUserLocalIsochPort, object ) ; 3387 if ( ! port ) 3388 { 3389 object->release() ; 3390 return kIOReturnBadArgument ; 3391 } 3392 3393 UInt64 chanSupported ; 3394 IOReturn result = kIOReturnSuccess ; 3395 3396 result = port->getSupported( *outMaxSpeed, chanSupported ) ; 3397 3398 *outChanSupportedHi = (UInt32)( chanSupported >> 32 ) ; 3399 *outChanSupportedLo = (UInt32)( chanSupported & 0xFFFFFFFF ) ; 3400 3401 port->release() ; 3402 3403 return result ; 3404} 3405 3406 3407IOReturn 3408IOFireWireUserClient::localIsochPort_Create ( 3409 LocalIsochPortAllocateParams* params, 3410 UserObjectHandle* outPortHandle ) 3411{ 3412 IOFWUserLocalIsochPort * port = OSTypeAlloc( IOFWUserLocalIsochPort ); 3413 if ( port && ! port->initWithUserDCLProgram( params, *this, *getOwner()->getController() ) ) 3414 { 3415 port->release() ; 3416 port = NULL ; 3417 } 3418 3419 if ( !port ) 3420 { 3421 DebugLog( "couldn't create local isoch port\n" ) ; 3422 return kIOReturnError ; 3423 } 3424 3425 IOReturn error = fExporter->addObject( port, 3426 &IOFWUserLocalIsochPort::exporterCleanup, 3427 outPortHandle ) ; 3428 3429 port->release() ; 3430 3431 return error ; 3432} 3433 3434IOReturn 3435IOFireWireUserClient::localIsochPort_SetChannel ( 3436 UserObjectHandle portHandle, 3437 UserObjectHandle channelHandle ) 3438{ 3439 InfoLog("IOFireWireUserClient<%p>::localIsochPort_SetChannel\n", this ) ; 3440 3441 const OSObject * object1 = fExporter->lookupObject( portHandle ) ; 3442 IOFWUserLocalIsochPort * port = OSDynamicCast ( IOFWUserLocalIsochPort, object1 ) ; 3443 IOReturn error = kIOReturnSuccess ; 3444 3445 if ( !port ) 3446 { 3447 error = kIOReturnBadArgument ; 3448 } 3449 3450 const OSObject * object2 = NULL ; 3451 IOFWUserIsochChannel * channel = NULL ; 3452 3453 if ( !error ) 3454 { 3455 object2 = fExporter->lookupObject( channelHandle ) ; 3456 3457 channel = OSDynamicCast( IOFWUserIsochChannel, object2 ) ; 3458 3459 if ( !channel ) 3460 { 3461 error = kIOReturnBadArgument ; 3462 } 3463 } 3464 3465 if ( !error ) 3466 { 3467 IODCLProgram * program = port->getProgramRef() ; 3468 if ( program ) 3469 { 3470 program->setForceStopProc( (IOFWIsochChannel::ForceStopNotificationProc*)&IOFWUserIsochChannel::isochChannel_ForceStopHandler, channel, channel ) ; 3471 3472 program->release() ; 3473 } 3474 } 3475 3476 if ( object1 ) 3477 { 3478 object1->release() ; 3479 } 3480 3481 if ( object2 ) 3482 { 3483 object2->release() ; 3484 } 3485 3486 return error ; 3487} 3488 3489IOReturn 3490IOFireWireUserClient::setAsyncRef_DCLCallProc ( 3491 OSAsyncReference64 asyncRef, 3492 UserObjectHandle portHandle ) 3493{ 3494 InfoLog("IOFireWireUserClient<%p>::setAsyncRef_DCLCallProc\n", this ) ; 3495 3496 const OSObject * object = fExporter->lookupObject( portHandle ) ; 3497 if ( !object ) 3498 { 3499 return kIOReturnBadArgument ; 3500 } 3501 3502 IOFWUserLocalIsochPort * port = OSDynamicCast( IOFWUserLocalIsochPort, object ) ; 3503 if ( ! port ) 3504 { 3505 object->release() ; 3506 return kIOReturnBadArgument ; 3507 } 3508 3509 IOReturn error = port->setAsyncRef_DCLCallProc( asyncRef ) ; 3510 3511 port->release() ; // loopkupObject retains the return value for thread safety 3512 3513 return error ; 3514} 3515 3516#pragma mark - 3517#pragma mark ISOCH CHANNEL 3518 3519IOReturn 3520IOFireWireUserClient::isochChannel_Create ( 3521 bool inDoIRM, 3522 UInt32 inPacketSize, 3523 IOFWSpeed inPrefSpeed, 3524 UserObjectHandle * outChannelHandle ) 3525{ 3526 // this code the same as IOFireWireController::createIsochChannel 3527 // must update this code when controller changes. We do this because 3528 // we are making IOFWUserIsochChannel objects, not IOFWIsochChannel 3529 // objects 3530 3531 IOReturn error = kIOReturnSuccess ; 3532 IOFWUserIsochChannel * channel = OSTypeAlloc( IOFWUserIsochChannel ); 3533 if ( channel ) 3534 { 3535 if ( channel->init( getOwner()->getController(), inDoIRM, inPacketSize, inPrefSpeed ) ) 3536 { 3537 fExporter->addObject( channel, 3538 (IOFWUserObjectExporter::CleanupFunction) & IOFWUserIsochChannel::s_exporterCleanup, 3539 outChannelHandle ) ; 3540 } 3541 3542 channel->release() ; // addObject retains the object 3543 } 3544 else 3545 { 3546 error = kIOReturnNoMemory ; 3547 } 3548 3549 return error ; 3550} 3551 3552IOReturn 3553IOFireWireUserClient::isochChannel_AllocateChannelBegin( 3554 UserObjectHandle channelRef, 3555 UInt32 speed, 3556 UInt32 chansHi, 3557 UInt32 chansLo, 3558 UInt32 * outSpeed, 3559 UInt32 * outChannel ) 3560{ 3561 InfoLog("IOFireWireUserClient<%p>::isochChannel_AllocateChannelBegin\n", this ) ; 3562 3563 IOReturn error = kIOReturnSuccess ; 3564 const OSObject * object = fExporter->lookupObject( channelRef ) ; 3565 3566 IOFWUserIsochChannel * channel = OSDynamicCast( IOFWUserIsochChannel, object ) ; 3567 3568 if ( ! channel ) 3569 { 3570 error = kIOReturnBadArgument ; 3571 } 3572 3573 if ( !error ) 3574 { 3575 UInt64 allowedChans = ((UInt64)chansHi << 32) | (UInt64)chansLo ; 3576 error = channel->allocateChannelBegin( (IOFWSpeed)speed, allowedChans, outChannel ) ; 3577 *outSpeed = speed; 3578 } 3579 3580 if ( object ) 3581 { 3582 object->release() ; // lookup retains object, so we have to release it. 3583 } 3584 3585 return error ; 3586} 3587 3588IOReturn 3589IOFireWireUserClient::setAsyncRef_IsochChannelForceStop( 3590 OSAsyncReference64 inAsyncRef, 3591 UserObjectHandle channelRef ) 3592{ 3593 3594 IOReturn error = kIOReturnSuccess; 3595 3596 const OSObject * object = fExporter->lookupObject( channelRef ) ; 3597 3598 IOFWUserIsochChannel * channel = OSDynamicCast( IOFWUserIsochChannel, object ) ; 3599 3600 if ( !channel ) 3601 { 3602#if __LP64__ 3603 DebugLog("IOFireWireUserClient<%p>::setAsyncRef_IsochChannelForceStop() -- invalid channel ref %llx\n", this, (UInt64)channelRef ) ; 3604#else 3605 DebugLog("IOFireWireUserClient<%p>::setAsyncRef_IsochChannelForceStop() -- invalid channel ref %lx\n", this, (UInt32)channelRef ) ; 3606#endif 3607 error = kIOReturnBadArgument ; 3608 } 3609 3610 io_user_reference_t * asyncRef = NULL; 3611 if( error == kIOReturnSuccess ) 3612 { 3613 asyncRef = new io_user_reference_t[ kOSAsyncRefCount ] ; 3614 3615 if ( !asyncRef ) 3616 { 3617 error = kIOReturnNoMemory ; 3618 } 3619 } 3620 3621 if( error == kIOReturnSuccess ) 3622 { 3623 bcopy( inAsyncRef, asyncRef, sizeof( OSAsyncReference64 ) ) ; 3624 3625 io_user_reference_t * oldAsyncRef = channel->getUserAsyncRef() ; 3626 3627 channel->setUserAsyncRef( asyncRef ) ; 3628 3629 delete [] oldAsyncRef ; 3630 } 3631 3632 if( channel != NULL ) 3633 { 3634 channel->release(); 3635 } 3636 3637 return error; 3638} 3639 3640#pragma mark - 3641#pragma mark COMMAND OBJECTS 3642 3643// createAsyncCommand 3644// 3645// 3646 3647IOReturn 3648IOFireWireUserClient::createAsyncCommand( OSAsyncReference64 asyncRef, 3649 CommandSubmitParams * params, 3650 UserObjectHandle * kernel_ref ) 3651{ 3652 IOReturn status = kIOReturnSuccess; 3653 3654 IOFWUserCommand * cmd = NULL; 3655 if( status == kIOReturnSuccess ) 3656 { 3657 cmd = IOFWUserCommand::withSubmitParams( params, this ); 3658 if( !cmd ) 3659 status = kIOReturnNoMemory; 3660 } 3661 3662 if( status == kIOReturnSuccess ) 3663 { 3664 status = fExporter->addObject( cmd, NULL, kernel_ref ); 3665 } 3666 3667 if( status == kIOReturnSuccess ) 3668 { 3669 cmd->setRefCon( (mach_vm_address_t)params->refCon); 3670 } 3671 3672 if( status == kIOReturnSuccess ) 3673 { 3674 setAsyncReference64( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)params->callback, (io_user_reference_t)params->refCon); 3675 3676 cmd->setAsyncReference64( asyncRef ); 3677 } 3678 3679 if( cmd ) 3680 { 3681 cmd->release(); // we need to release this in all cases 3682 cmd = NULL; 3683 } 3684 3685 return status; 3686} 3687 3688 3689IOReturn 3690IOFireWireUserClient::userAsyncCommand_Submit( 3691 OSAsyncReference64 asyncRef, 3692 CommandSubmitParams * params, 3693 CommandSubmitResult * outResult, 3694 IOByteCount paramsSize, 3695 IOByteCount * outResultSize) 3696{ 3697 IOFWUserCommand * cmd = NULL ; 3698 3699 IOReturn error = kIOReturnSuccess ; 3700 3701 if ( params->kernCommandRef ) 3702 { 3703 const OSObject * object = fExporter->lookupObject( params->kernCommandRef ) ; 3704 if ( !object ) 3705 { 3706 error = kIOReturnBadArgument ; 3707 } 3708 else 3709 { 3710 cmd = OSDynamicCast( IOFWUserCommand, object ) ; 3711 if ( ! cmd ) 3712 { 3713 object->release() ; 3714 error = kIOReturnBadArgument ; 3715 } 3716 } 3717 } 3718 else 3719 { 3720 cmd = IOFWUserCommand::withSubmitParams( params, this ) ; 3721 3722 if ( ! cmd ) 3723 error = kIOReturnNoMemory ; 3724 else 3725 { 3726 UserObjectHandle command_ref; 3727 error = fExporter->addObject( cmd, NULL, &command_ref ); 3728 outResult->kernCommandRef = command_ref; 3729 } 3730 } 3731 3732 if ( cmd ) 3733 { 3734 if ( !error ) 3735 { 3736 super::setAsyncReference64( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)params->callback, (io_user_reference_t)params->refCon) ; 3737 3738 cmd->setAsyncReference64( asyncRef ) ; 3739 cmd->setRefCon( (mach_vm_address_t)params->refCon); 3740 3741 error = cmd->submit( params, outResult ) ; 3742 } 3743 3744 cmd->release() ; // we need to release this in all cases 3745 } 3746 3747 return error ; 3748} 3749 3750// 3751// --- absolute address firewire commands ---------- 3752// 3753IOFWReadCommand* 3754IOFireWireUserClient::createReadCommand( 3755 UInt32 generation, 3756 FWAddress devAddress, 3757 IOMemoryDescriptor* hostMem, 3758 FWDeviceCallback completion, 3759 void* refcon ) const 3760{ 3761 IOFWReadCommand* result = OSTypeAlloc( IOFWReadCommand ); 3762 if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, hostMem, completion, refcon ) ) 3763 { 3764 result->release() ; 3765 result = NULL ; 3766 } 3767 3768 return result ; 3769} 3770 3771IOFWReadQuadCommand* 3772IOFireWireUserClient::createReadQuadCommand( 3773 UInt32 generation, 3774 FWAddress devAddress, 3775 UInt32 * quads, 3776 int numQuads, 3777 FWDeviceCallback completion, 3778 void * refcon ) const 3779{ 3780 IOFWReadQuadCommand* result = OSTypeAlloc( IOFWReadQuadCommand ); 3781 if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, quads, numQuads, completion, refcon ) ) 3782 { 3783 result->release() ; 3784 return NULL ; 3785 } 3786 3787 return result ; 3788} 3789 3790IOFWWriteCommand* 3791IOFireWireUserClient::createWriteCommand( 3792 UInt32 generation, 3793 FWAddress devAddress, 3794 IOMemoryDescriptor* hostMem, 3795 FWDeviceCallback completion, 3796 void* refcon ) const 3797{ 3798 IOFWWriteCommand* result = OSTypeAlloc( IOFWWriteCommand ); 3799 if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, hostMem, completion, refcon ) ) 3800 { 3801 result->release() ; 3802 return NULL ; 3803 } 3804 3805 return result ; 3806} 3807 3808IOFWWriteQuadCommand* 3809IOFireWireUserClient::createWriteQuadCommand( 3810 UInt32 generation, 3811 FWAddress devAddress, 3812 UInt32 * quads, 3813 int numQuads, 3814 FWDeviceCallback completion, 3815 void * refcon ) const 3816{ 3817 IOFWWriteQuadCommand* result = OSTypeAlloc( IOFWWriteQuadCommand ); 3818 if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, quads, numQuads, completion, refcon ) ) 3819 { 3820 result->release() ; 3821 return NULL ; 3822 } 3823 3824 return result ; 3825} 3826 3827 // size is 1 for 32 bit compare, 2 for 64 bit. 3828IOFWCompareAndSwapCommand* 3829IOFireWireUserClient::createCompareAndSwapCommand( 3830 UInt32 generation, 3831 FWAddress devAddress, 3832 const UInt32 * cmpVal, 3833 const UInt32 * newVal, 3834 int size, 3835 FWDeviceCallback completion, 3836 void * refcon ) const 3837{ 3838 IOFWCompareAndSwapCommand* result = OSTypeAlloc( IOFWCompareAndSwapCommand ); 3839 if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, cmpVal, newVal, size, completion, refcon ) ) 3840 { 3841 result->release() ; 3842 return NULL ; 3843 } 3844 3845 return result ; 3846} 3847 3848#pragma mark - 3849 3850IOReturn 3851IOFireWireUserClient::firelog( const char* string, IOByteCount bufSize ) const 3852{ 3853 3854#if FIRELOG 3855 FireLog( string ) ; 3856#endif 3857 3858 return kIOReturnSuccess; 3859} 3860 3861IOReturn 3862IOFireWireUserClient::getBusGeneration( UInt32* outGeneration ) 3863{ 3864 *outGeneration = getOwner () -> getController () -> getGeneration () ; 3865 return kIOReturnSuccess ; 3866} 3867 3868IOReturn 3869IOFireWireUserClient::getLocalNodeIDWithGeneration( UInt32 testGeneration, UInt32* outLocalNodeID ) 3870{ 3871 if ( ! getOwner () -> getController () -> checkGeneration ( testGeneration ) ) 3872 return kIOFireWireBusReset ; 3873 3874 *outLocalNodeID = (UInt32) getOwner () -> getController () -> getLocalNodeID () ; 3875 3876 // did generation change when we weren't looking? 3877 if ( ! getOwner () -> getController () -> checkGeneration ( testGeneration ) ) 3878 return kIOFireWireBusReset ; 3879 3880 return kIOReturnSuccess ; 3881} 3882 3883IOReturn 3884IOFireWireUserClient::getRemoteNodeID( UInt32 testGeneration, UInt32* outRemoteNodeID ) 3885{ 3886 UInt32 generation ; 3887 UInt16 nodeID ; 3888 3889 IOReturn error = getOwner () -> getNodeIDGeneration ( generation, nodeID ) ; 3890 if (error) 3891 return error ; 3892 if ( generation != testGeneration ) 3893 return kIOFireWireBusReset ; 3894 3895 *outRemoteNodeID = (UInt32)nodeID ; 3896 3897 // did generation change when we weren't looking? 3898 if ( ! getOwner () -> getController () -> checkGeneration ( generation ) ) 3899 return kIOFireWireBusReset ; 3900 3901 return error ; 3902} 3903 3904IOReturn 3905IOFireWireUserClient::getSpeedToNode( UInt32 generation, UInt32* outSpeed ) 3906{ 3907 if ( ! getOwner () -> getController () -> checkGeneration ( generation ) ) 3908 return kIOFireWireBusReset ; 3909 3910 UInt16 nodeID ; 3911 getOwner () -> getNodeIDGeneration( generation, nodeID ) ; 3912 3913 *outSpeed = (UInt32) getOwner () -> getController () -> FWSpeed ( nodeID ) ; 3914 3915 // did generation change when we weren't looking? 3916 if ( ! getOwner () -> getController () -> checkGeneration ( generation ) ) 3917 return kIOFireWireBusReset ; 3918 3919 return kIOReturnSuccess ; 3920} 3921 3922IOReturn 3923IOFireWireUserClient::getSpeedBetweenNodes( UInt32 generation, UInt32 fromNode, UInt32 toNode, UInt32* outSpeed ) 3924{ 3925 if ( ! getOwner () -> getController () -> checkGeneration ( generation ) ) 3926 return kIOFireWireBusReset ; 3927 3928 *outSpeed = (UInt32)getOwner ()->getController()->FWSpeed( (UInt16)fromNode, (UInt16)toNode ) ; 3929 // did generation change when we weren't looking? 3930 if (!getOwner ()->getController()->checkGeneration(generation)) 3931 return kIOFireWireBusReset ; 3932 3933 return kIOReturnSuccess ; 3934} 3935 3936IOReturn 3937IOFireWireUserClient::getIRMNodeID( UInt32 generation, UInt32* irmNodeID ) 3938{ 3939 UInt16 tempNodeID ; 3940 UInt32 tempGeneration ; 3941 3942 IOReturn error = (UInt32)getOwner ()->getController()->getIRMNodeID( tempGeneration, tempNodeID ) ; 3943 if (error) 3944 return error ; 3945 3946 if ( tempGeneration != generation ) 3947 return kIOFireWireBusReset ; 3948 3949 *irmNodeID = (UInt32)tempNodeID ; 3950 3951 return kIOReturnSuccess ; 3952} 3953 3954IOReturn 3955IOFireWireUserClient::clipMaxRec2K( Boolean clipMaxRec ) 3956{ 3957 //IOLog("IOFireWireUserClient::clipMaxRec2K\n"); 3958 3959 if( fClippedMaxRec == clipMaxRec ) 3960 return kIOReturnSuccess; // Already set the way we want, no need to do it again 3961 3962 IOReturn error = (UInt32)fOwner->getController()->clipMaxRec2K( clipMaxRec ) ; 3963 if (error) 3964 return error ; 3965 3966 fClippedMaxRec = clipMaxRec; 3967 3968 return kIOReturnSuccess ; 3969} 3970 3971IOReturn 3972IOFireWireUserClient::seize( IOOptionBits inFlags ) 3973{ 3974 if ( ! OSDynamicCast(IOFireWireDevice, getOwner ())) 3975 return kIOReturnUnsupported ; 3976 3977 if ( kIOReturnSuccess != clientHasPrivilege( fTask, kIOClientPrivilegeAdministrator ) ) 3978 return kIOReturnNotPrivileged ; 3979 3980 // message all clients that have the device open that 3981 // the device is going away. It's not really going away, but we 3982 // want them to think so... 3983 if ( getOwner ()->isOpen() ) 3984 { 3985 OSIterator* clientIterator = getOwner ()->getOpenClientIterator() ; 3986 if (!clientIterator) 3987 { 3988 DebugLog("IOFireWireUserClient::seize: couldn't make owner client iterator\n") ; 3989 return kIOReturnError ; 3990 } 3991 3992 { 3993 IOService* client = (IOService*)clientIterator->getNextObject() ; 3994 3995 while ( client ) 3996 { 3997 if ( client != this ) 3998 { 3999 client->message( kIOFWMessageServiceIsRequestingClose, getOwner () ) ; 4000 client->message( kIOMessageServiceIsRequestingClose, getOwner () ) ; 4001 4002 client->terminate() ; 4003 } 4004 4005 client = (IOService*)clientIterator->getNextObject() ; 4006 } 4007 } 4008 4009 clientIterator->release() ; 4010 } 4011 4012 if ( getOwner ()->isOpen() ) 4013 { 4014 OSIterator* clientIterator = getOwner ()->getClientIterator() ; 4015 if (!clientIterator) 4016 { 4017 DebugLog("IOFireWireUserClient::seize: couldn't make owner client iterator\n") ; 4018 return kIOReturnError ; 4019 } 4020 4021 { 4022 IOService* client = (IOService*)clientIterator->getNextObject() ; 4023 4024 while ( client ) 4025 { 4026 if ( client != this ) 4027 { 4028 client->message( kIOFWMessageServiceIsRequestingClose, getOwner () ) ; 4029 client->message( kIOMessageServiceIsRequestingClose, getOwner () ) ; 4030 4031 client->terminate() ; 4032 } 4033 4034 client = (IOService*)clientIterator->getNextObject() ; 4035 } 4036 } 4037 4038 clientIterator->release() ; 4039 } 4040 4041 return kIOReturnSuccess ; 4042} 4043 4044IOReturn IOFireWireUserClient::message( UInt32 type, IOService * provider, void * arg ) 4045{ 4046 switch(type) 4047 { 4048 case kIOMessageServiceIsSuspended: 4049 if (fBusResetAsyncNotificationRef[0]) 4050 sendAsyncResult64(fBusResetAsyncNotificationRef, kIOReturnSuccess, NULL, 0) ; 4051 break ; 4052 case kIOMessageServiceIsResumed: 4053 if (fBusResetDoneAsyncNotificationRef[0]) 4054 sendAsyncResult64(fBusResetDoneAsyncNotificationRef, kIOReturnSuccess, NULL, 0) ; 4055 break ; 4056 case kIOFWMessageServiceIsRequestingClose: 4057 getOwner ()->messageClients(kIOMessageServiceIsRequestingClose) ; 4058 break; 4059 4060 } 4061 4062 super::message ( type, provider ) ; 4063 4064 return kIOReturnSuccess; 4065} 4066 4067IOReturn 4068IOFireWireUserClient::getSessionRef( IOFireWireSessionRef * sessionRef ) 4069{ 4070 IOReturn error = kIOReturnSuccess; 4071 4072 if( !fOwner->isOpen( this ) ) 4073 { 4074 return kIOReturnNotOpen ; 4075 } 4076 4077 *sessionRef = (IOFireWireSessionRef)fSessionRef; 4078 4079 return error ; 4080} 4081 4082#pragma mark - 4083#pragma mark ASYNC STREAM LISTENER 4084 4085// 4086// Async Stream Listener 4087// 4088 4089IOReturn 4090IOFireWireUserClient::setAsyncStreamRef_Packet ( 4091 OSAsyncReference64 asyncRef, 4092 UserObjectHandle asyncStreamListenerHandle, 4093 mach_vm_address_t inCallback, 4094 io_user_reference_t inUserRefCon, 4095 void*, 4096 void*, 4097 void* 4098) 4099{ 4100 IOReturn result = kIOReturnBadArgument; 4101 4102 const OSObject * object = fExporter->lookupObject ( asyncStreamListenerHandle ) ; 4103 if ( !object ) 4104 { 4105 return result ; 4106 } 4107 4108 IOFWUserAsyncStreamListener * me = OSDynamicCast ( IOFWUserAsyncStreamListener, object ) ; 4109 if ( ! me ) 4110 { 4111 object->release() ; 4112 return result ; 4113 } 4114 4115 if ( inCallback ) 4116 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ; 4117 else 4118 asyncRef[0] = 0 ; 4119 4120 me->setAsyncStreamRef_Packet(asyncRef) ; 4121 me->release() ; 4122 4123 return kIOReturnSuccess ; 4124} 4125 4126IOReturn 4127IOFireWireUserClient::setAsyncStreamRef_SkippedPacket ( 4128 OSAsyncReference64 asyncRef, 4129 UserObjectHandle inAsyncStreamListenerRef, 4130 mach_vm_address_t inCallback, 4131 io_user_reference_t inUserRefCon, 4132 void*, 4133 void*, 4134 void*) 4135{ 4136 IOReturn result = kIOReturnBadArgument; 4137 4138 const OSObject * object = fExporter->lookupObject ( inAsyncStreamListenerRef ) ; 4139 if ( !object ) 4140 { 4141 return result ; 4142 } 4143 4144 result = kIOReturnSuccess ; 4145 IOFWUserAsyncStreamListener * me = OSDynamicCast ( IOFWUserAsyncStreamListener, object ) ; 4146 4147 if ( !me ) 4148 { 4149 object->release() ; 4150 result = kIOReturnBadArgument ; 4151 } 4152 4153 if ( kIOReturnSuccess == result ) 4154 { 4155 if (inCallback) 4156 super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ; 4157 else 4158 asyncRef[0] = 0 ; 4159 4160 me->setAsyncStreamRef_SkippedPacket(asyncRef) ; 4161 } 4162 4163 me->release(); 4164 4165 return result ; 4166} 4167 4168IOReturn 4169IOFireWireUserClient::asyncStreamListener_Create ( 4170 FWUserAsyncStreamListenerCreateParams* params, 4171 UserObjectHandle* outAsyncStreamListenerHandle ) 4172{ 4173 IOFWUserAsyncStreamListener * asyncStreamListener = OSTypeAlloc( IOFWUserAsyncStreamListener ); 4174 4175 if ( asyncStreamListener == NULL ) 4176 return kIOReturnNoMemory ; 4177 4178 if ( not asyncStreamListener->initAsyncStreamListener( this, params ) ) 4179 { 4180 asyncStreamListener->release(); 4181 return kIOReturnNoMemory ; 4182 } 4183 4184 IOReturn error = fExporter->addObject ( asyncStreamListener, 4185 (IOFWUserObjectExporter::CleanupFunction)&IOFWUserAsyncStreamListener::exporterCleanup, 4186 outAsyncStreamListenerHandle ) ; // nnn needs cleanup function? 4187 4188 if ( error ) 4189 asyncStreamListener->deactivate() ; 4190 4191 asyncStreamListener->release() ; 4192 4193 return error ; 4194} 4195 4196IOReturn 4197IOFireWireUserClient::asyncStreamListener_ClientCommandIsComplete ( 4198 UserObjectHandle asyncStreamListenerHandle, 4199 FWClientCommandID inCommandID ) 4200{ 4201 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4202 if ( !object ) 4203 { 4204 return kIOReturnBadArgument ; 4205 } 4206 4207 IOReturn result = kIOReturnSuccess ; 4208 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4209 if (!me) 4210 { 4211 object->release() ; 4212 return kIOReturnBadArgument ; 4213 } 4214 4215 me->clientCommandIsComplete ( inCommandID ) ; 4216 me->release() ; 4217 4218 return result ; 4219} 4220 4221IOReturn 4222IOFireWireUserClient::asyncStreamListener_GetOverrunCounter ( 4223 UserObjectHandle asyncStreamListenerHandle, 4224 UInt32 *overrunCounter ) 4225{ 4226 IOReturn result = kIOReturnBadArgument ; 4227 4228 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4229 if ( !object ) 4230 { 4231 return result ; 4232 } 4233 4234 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4235 if ( !me ) 4236 { 4237 object->release() ; 4238 return result ; 4239 } 4240 4241 *overrunCounter = me->getOverrunCounter( ) ; 4242 me->release() ; 4243 4244 result = kIOReturnSuccess; 4245 4246 return result ; 4247 4248} 4249 4250IOReturn 4251IOFireWireUserClient::asyncStreamListener_SetFlags ( 4252 UserObjectHandle asyncStreamListenerHandle, 4253 UInt32 flags ) 4254{ 4255 IOReturn result = kIOReturnBadArgument ; 4256 4257 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4258 if ( !object ) 4259 { 4260 return result ; 4261 } 4262 4263 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4264 if (!me) 4265 { 4266 object->release() ; 4267 return result; 4268 } 4269 4270 result = kIOReturnSuccess; 4271 me->setFlags( flags ) ; 4272 me->release() ; 4273 4274 return result ; 4275} 4276 4277IOReturn 4278IOFireWireUserClient::asyncStreamListener_GetFlags ( 4279 UserObjectHandle asyncStreamListenerHandle, 4280 UInt32 *flags ) 4281{ 4282 IOReturn result = kIOReturnBadArgument ; 4283 4284 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4285 if ( !object ) 4286 { 4287 return result ; 4288 } 4289 4290 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4291 if (!me) 4292 { 4293 object->release() ; 4294 return result ; 4295 } 4296 4297 result = kIOReturnSuccess; 4298 *flags = me->getFlags( ) ; 4299 me->release() ; 4300 4301 return result ; 4302} 4303 4304IOReturn 4305IOFireWireUserClient::asyncStreamListener_TurnOnNotification ( 4306 UserObjectHandle asyncStreamListenerHandle ) 4307{ 4308 IOReturn result = kIOReturnBadArgument ; 4309 4310 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4311 if ( !object ) 4312 { 4313 return result ; 4314 } 4315 4316 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4317 if (!me) 4318 { 4319 object->release() ; 4320 return result ; 4321 } 4322 4323 result = kIOReturnSuccess; 4324 me->TurnOnNotification() ; 4325 me->release() ; 4326 4327 return result ; 4328} 4329 4330IOReturn 4331IOFireWireUserClient::asyncStreamListener_TurnOffNotification ( 4332 UserObjectHandle asyncStreamListenerHandle ) 4333{ 4334 IOReturn result = kIOReturnBadArgument ; 4335 4336 const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ; 4337 if ( !object ) 4338 { 4339 return result ; 4340 } 4341 4342 IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ; 4343 if (!me) 4344 { 4345 object->release() ; 4346 return result ; 4347 } 4348 4349 result = kIOReturnSuccess; 4350 me->TurnOffNotification() ; 4351 me->release() ; 4352 4353 return result ; 4354} 4355 4356#pragma mark - 4357#pragma mark IRM ALLOCATIONS 4358 4359IOReturn 4360IOFireWireUserClient::allocateIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation) 4361{ 4362 return getOwner () -> getController () -> allocateIRMBandwidthInGeneration(bandwidthUnits, generation); 4363} 4364 4365IOReturn 4366IOFireWireUserClient::releaseIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation) 4367{ 4368 return getOwner () -> getController () -> releaseIRMBandwidthInGeneration(bandwidthUnits, generation); 4369} 4370 4371IOReturn 4372IOFireWireUserClient::allocateIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation) 4373{ 4374 return getOwner () -> getController () -> allocateIRMChannelInGeneration(isochChannel, generation); 4375} 4376 4377IOReturn 4378IOFireWireUserClient::releaseIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation) 4379{ 4380 return getOwner () -> getController () -> releaseIRMChannelInGeneration(isochChannel, generation); 4381} 4382 4383typedef struct UserIRMAllocationParamsStruct 4384{ 4385 io_user_reference_t asyncRef[kOSAsyncRef64Count]; 4386 Boolean userNotificationEnabled; 4387 IOFireWireUserClient *pUserClient; 4388} UserIRMAllocationParams; 4389 4390static void UserIRMAllocationCleanupFunction( const OSObject * obj ) 4391{ 4392 IOFireWireIRMAllocation * pIrmAllocation = (IOFireWireIRMAllocation *) obj; 4393 4394 UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) pIrmAllocation->GetRefCon(); 4395 delete pUserIRMAllocationParams; 4396} 4397 4398static IOReturn UserIRMAllocationLostNotification(void* refCon, class IOFireWireIRMAllocation* allocation) 4399{ 4400 UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) refCon; 4401 if (pUserIRMAllocationParams->userNotificationEnabled) 4402 pUserIRMAllocationParams->pUserClient->sendAsyncResult64(pUserIRMAllocationParams->asyncRef, kIOReturnSuccess, NULL, 0) ; 4403 return kIOReturnSuccess; 4404} 4405 4406IOReturn 4407IOFireWireUserClient::irmAllocation_Create(Boolean releaseIRMResourcesOnFree, UserObjectHandle* outIRMAllocationHandle) 4408{ 4409 UserIRMAllocationParams *pUserIRMAllocationParams = new UserIRMAllocationParams; 4410 if (!pUserIRMAllocationParams) 4411 return kIOReturnNoMemory ; 4412 else 4413 { 4414 pUserIRMAllocationParams->userNotificationEnabled = false; 4415 pUserIRMAllocationParams->pUserClient = this; 4416 } 4417 4418 IOFireWireIRMAllocation * irmAllocation = OSTypeAlloc( IOFireWireIRMAllocation ); 4419 if (!irmAllocation) 4420 { 4421 delete pUserIRMAllocationParams; 4422 return kIOReturnNoMemory ; 4423 } 4424 4425 if (!irmAllocation->init(getOwner()->getController(), releaseIRMResourcesOnFree, UserIRMAllocationLostNotification, pUserIRMAllocationParams)) 4426 { 4427 irmAllocation->release(); 4428 delete pUserIRMAllocationParams; 4429 return kIOReturnNoMemory ; 4430 } 4431 4432 IOReturn error = fExporter->addObject ( irmAllocation, UserIRMAllocationCleanupFunction, outIRMAllocationHandle ) ; 4433 irmAllocation->release() ; 4434 4435 return error ; 4436} 4437 4438IOReturn 4439IOFireWireUserClient::irmAllocation_AllocateResources(UserObjectHandle irmAllocationHandle, UInt8 isochChannel, UInt32 bandwidthUnits) 4440{ 4441 IOReturn result = kIOReturnBadArgument ; 4442 4443 const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ; 4444 if ( !object ) 4445 { 4446 return result ; 4447 } 4448 4449 IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ; 4450 if (!me) 4451 { 4452 object->release() ; 4453 return result ; 4454 } 4455 4456 result = me->allocateIsochResources(isochChannel, bandwidthUnits) ; 4457 4458 me->release() ; 4459 4460 return result ; 4461} 4462 4463IOReturn 4464IOFireWireUserClient::irmAllocation_DeallocateResources(UserObjectHandle irmAllocationHandle) 4465{ 4466 IOReturn result = kIOReturnBadArgument ; 4467 4468 const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ; 4469 if ( !object ) 4470 { 4471 return result ; 4472 } 4473 4474 IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ; 4475 if (!me) 4476 { 4477 object->release() ; 4478 return result ; 4479 } 4480 4481 result = me->deallocateIsochResources(); 4482 4483 me->release() ; 4484 4485 return result ; 4486} 4487 4488Boolean 4489IOFireWireUserClient::irmAllocation_areResourcesAllocated(UserObjectHandle irmAllocationHandle, UInt8 *pIsochChannel, UInt32 *pBandwidthUnits) 4490{ 4491 Boolean result = false ; 4492 4493 const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ; 4494 if ( !object ) 4495 { 4496 return false ; 4497 } 4498 4499 IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ; 4500 if (!me) 4501 { 4502 object->release() ; 4503 return false ; 4504 } 4505 4506 result = me->areIsochResourcesAllocated(pIsochChannel, pBandwidthUnits); 4507 4508 me->release() ; 4509 4510 return result ; 4511} 4512 4513void 4514IOFireWireUserClient::irmAllocation_setDeallocateOnRelease(UserObjectHandle irmAllocationHandle, Boolean doDeallocationOnRelease) 4515{ 4516 const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ; 4517 if ( !object ) 4518 { 4519 return; 4520 } 4521 4522 IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ; 4523 if (!me) 4524 { 4525 object->release() ; 4526 return; 4527 } 4528 4529 me->setReleaseIRMResourcesOnFree(doDeallocationOnRelease); 4530 4531 me->release() ; 4532 4533 return; 4534} 4535 4536IOReturn 4537IOFireWireUserClient::irmAllocation_setRef(OSAsyncReference64 asyncRef, 4538 UserObjectHandle irmAllocationHandle, 4539 io_user_reference_t inCallback, 4540 io_user_reference_t inUserRefCon) 4541{ 4542 IOReturn result = kIOReturnBadArgument ; 4543 4544 const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ; 4545 if ( !object ) 4546 { 4547 return result ; 4548 } 4549 4550 IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ; 4551 if (!me) 4552 { 4553 object->release() ; 4554 return result ; 4555 } 4556 4557 UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) me->GetRefCon(); 4558 4559 for (UInt32 i=0;i<kOSAsyncRef64Count;i++) 4560 pUserIRMAllocationParams->asyncRef[i] = asyncRef[i]; 4561 pUserIRMAllocationParams->asyncRef[ kIOAsyncCalloutFuncIndex ] = (mach_vm_address_t)inCallback ; 4562 pUserIRMAllocationParams->asyncRef[ kIOAsyncCalloutRefconIndex ] = inUserRefCon ; 4563 if (inCallback) 4564 pUserIRMAllocationParams->userNotificationEnabled = true; 4565 else 4566 pUserIRMAllocationParams->userNotificationEnabled = false; 4567 4568 me->release() ; 4569 4570 return result ; 4571} 4572 4573// createVectorCommand 4574// 4575// 4576 4577IOReturn 4578IOFireWireUserClient::createVectorCommand( UserObjectHandle * kernel_ref ) 4579{ 4580 IOReturn status = kIOReturnSuccess; 4581 4582 IOFWUserVectorCommand * cmd = NULL; 4583 if( status == kIOReturnSuccess ) 4584 { 4585 cmd = IOFWUserVectorCommand::withUserClient( this ); 4586 if( !cmd ) 4587 status = kIOReturnNoMemory; 4588 } 4589 4590 if( status == kIOReturnSuccess ) 4591 { 4592 status = fExporter->addObject( cmd, NULL, kernel_ref ); 4593 } 4594 4595 if( cmd ) 4596 { 4597 cmd->release(); // we need to release this in all cases 4598 cmd = NULL; 4599 } 4600 4601 return status; 4602} 4603 4604// createPHYPacketListener 4605// 4606// 4607 4608IOReturn 4609IOFireWireUserClient::createPHYPacketListener( UInt32 queue_count, UserObjectHandle * kernel_ref ) 4610{ 4611 IOReturn status = kIOReturnSuccess; 4612 4613 IOFWUserPHYPacketListener * listener = NULL; 4614 if( status == kIOReturnSuccess ) 4615 { 4616 listener = IOFWUserPHYPacketListener::withUserClient( this, queue_count ); 4617 if( !listener ) 4618 status = kIOReturnNoMemory; 4619 } 4620 4621 if( status == kIOReturnSuccess ) 4622 { 4623 status = fExporter->addObject( listener, (IOFWUserObjectExporter::CleanupFunction)&IOFWUserPHYPacketListener::exporterCleanup, kernel_ref ); 4624 } 4625 4626 if( listener ) 4627 { 4628 listener->release(); // we need to release this in all cases 4629 listener = NULL; 4630 } 4631 4632 return status; 4633} 4634