|
|
1.1 ! root 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) 1998 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * HISTORY ! 26: * ! 27: * 14 Aug 98 sdouglas created. ! 28: * 08 Dec 98 sdouglas cpp. ! 29: */ ! 30: ! 31: #include <IOKit/IOKitServer.h> ! 32: #include <IOKit/IOUserClient.h> ! 33: #include <IOKit/IOService.h> ! 34: #include <IOKit/IORegistryEntry.h> ! 35: #include <IOKit/IOCatalogue.h> ! 36: #include <IOKit/IOMemoryDescriptor.h> ! 37: #include <IOKit/IOLib.h> ! 38: ! 39: #include "../bsddev/IOKitBSDInit.h" ! 40: ! 41: #include <IOKit/assert.h> ! 42: ! 43: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 44: ! 45: // definitions we should get from osfmk ! 46: ! 47: //typedef struct ipc_port * ipc_port_t; ! 48: typedef natural_t ipc_kobject_type_t; ! 49: ! 50: #define IKOT_IOKIT_SPARE 27 ! 51: #define IKOT_IOKIT_CONNECT 29 ! 52: #define IKOT_IOKIT_OBJECT 30 ! 53: ! 54: extern "C" { ! 55: ! 56: extern ipc_port_t iokit_alloc_object_port( io_object_t obj, ! 57: ipc_kobject_type_t type ); ! 58: ! 59: extern kern_return_t iokit_destroy_object_port( ipc_port_t port ); ! 60: ! 61: extern mach_port_name_t iokit_make_send_right( task_t task, ! 62: io_object_t obj, ipc_kobject_type_t type ); ! 63: ! 64: extern ipc_port_t master_device_port; ! 65: ! 66: extern vm_size_t msg_ool_size_small; ! 67: ! 68: extern kern_return_t vm_map_copyin_common( ! 69: vm_map_t src_map, ! 70: vm_offset_t src_addr, ! 71: vm_size_t len, ! 72: boolean_t src_destroy, ! 73: boolean_t src_volatile, ! 74: vm_map_copy_t *copy_result, /* OUT */ ! 75: boolean_t use_maxprot); ! 76: ! 77: #define vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result) \ ! 78: vm_map_copyin_common(src_map, src_addr, len, src_destroy, \ ! 79: FALSE, copy_result, FALSE) ! 80: ! 81: extern kern_return_t vm_map_copyout( ! 82: vm_map_t dst_map, ! 83: vm_offset_t *dst_addr, /* OUT */ ! 84: vm_map_copy_t copy); ! 85: ! 86: } /* extern "C" */ ! 87: ! 88: ! 89: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 90: ! 91: // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject. ! 92: ! 93: class IOMachPort : public OSObject ! 94: { ! 95: OSDeclareDefaultStructors(IOMachPort) ! 96: public: ! 97: OSObject * object; ! 98: ipc_port_t port; ! 99: ! 100: static IOMachPort * portForObject( OSObject * obj, ! 101: ipc_kobject_type_t type ); ! 102: static void releasePortForObject( OSObject * obj, ! 103: ipc_kobject_type_t type ); ! 104: static OSDictionary * dictForType( ipc_kobject_type_t type ); ! 105: ! 106: static mach_port_name_t makeSendRightForTask( task_t task, ! 107: io_object_t obj, ipc_kobject_type_t type ); ! 108: ! 109: virtual void free(); ! 110: }; ! 111: ! 112: #define super OSObject ! 113: OSDefineMetaClassAndStructors(IOMachPort, OSObject) ! 114: ! 115: static IOLock * gIOObjectPortLock; ! 116: ! 117: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 118: ! 119: // not in dictForType() for debugging ease ! 120: static OSDictionary * gIOObjectPorts; ! 121: static OSDictionary * gIOConnectPorts; ! 122: ! 123: OSDictionary * IOMachPort::dictForType( ipc_kobject_type_t type ) ! 124: { ! 125: OSDictionary ** dict; ! 126: ! 127: if( IKOT_IOKIT_OBJECT == type ) ! 128: dict = &gIOObjectPorts; ! 129: else if( IKOT_IOKIT_CONNECT == type ) ! 130: dict = &gIOConnectPorts; ! 131: else ! 132: return( 0 ); ! 133: ! 134: if( 0 == *dict) ! 135: *dict = OSDictionary::withCapacity( 1 ); ! 136: ! 137: return( *dict ); ! 138: } ! 139: ! 140: IOMachPort * IOMachPort::portForObject ( OSObject * obj, ! 141: ipc_kobject_type_t type ) ! 142: { ! 143: IOMachPort * inst = 0; ! 144: OSDictionary * dict; ! 145: ! 146: IOTakeLock( gIOObjectPortLock); ! 147: ! 148: do { ! 149: ! 150: dict = dictForType( type ); ! 151: if( !dict) ! 152: continue; ! 153: ! 154: if( (inst = (IOMachPort *) ! 155: dict->getObject( (const OSSymbol *) obj ))) ! 156: continue; ! 157: ! 158: inst = new IOMachPort; ! 159: if( inst && !inst->init()) { ! 160: inst = 0; ! 161: continue; ! 162: } ! 163: ! 164: inst->port = iokit_alloc_object_port( obj, type ); ! 165: if( inst->port) { ! 166: // retains obj ! 167: dict->setObject( (const OSSymbol *) obj, inst ); ! 168: inst->release(); // one more to free port => release obj ! 169: ! 170: } else { ! 171: inst->release(); ! 172: inst = 0; ! 173: } ! 174: ! 175: } while( false ); ! 176: ! 177: IOUnlock( gIOObjectPortLock); ! 178: ! 179: return( inst ); ! 180: } ! 181: ! 182: void IOMachPort::releasePortForObject( OSObject * obj, ! 183: ipc_kobject_type_t type ) ! 184: { ! 185: OSDictionary * dict; ! 186: ! 187: IOTakeLock( gIOObjectPortLock); ! 188: ! 189: if( (dict = dictForType( type ))) ! 190: dict->removeObject( (const OSSymbol *) obj ); ! 191: ! 192: IOUnlock( gIOObjectPortLock); ! 193: } ! 194: ! 195: void IOUserClient::destroyUserReferences( OSObject * obj ) ! 196: { ! 197: IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT ); ! 198: IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT ); ! 199: } ! 200: ! 201: mach_port_name_t IOMachPort::makeSendRightForTask( task_t task, ! 202: io_object_t obj, ipc_kobject_type_t type ) ! 203: { ! 204: return( iokit_make_send_right( task, obj, type )); ! 205: } ! 206: ! 207: void IOMachPort::free( void ) ! 208: { ! 209: if( port) ! 210: iokit_destroy_object_port( port ); ! 211: super::free(); ! 212: } ! 213: ! 214: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 215: ! 216: extern "C" { ! 217: ! 218: // functions called from osfmk/device/iokit_rpc.c ! 219: ! 220: void ! 221: iokit_add_reference( io_object_t obj ) ! 222: { ! 223: if( obj) ! 224: obj->retain(); ! 225: } ! 226: ! 227: void ! 228: iokit_remove_reference( io_object_t obj ) ! 229: { ! 230: if( obj) ! 231: obj->release(); ! 232: } ! 233: ! 234: ipc_port_t ! 235: iokit_port_for_object( io_object_t obj, ipc_kobject_type_t type ) ! 236: { ! 237: IOMachPort * machPort; ! 238: ! 239: if( (machPort = IOMachPort::portForObject( obj, type ))) ! 240: return( machPort->port ); ! 241: else ! 242: return( 0 ); ! 243: } ! 244: ! 245: kern_return_t ! 246: iokit_client_died( io_object_t obj, ipc_port_t /* port */, ! 247: ipc_kobject_type_t type ) ! 248: { ! 249: IOUserClient * client; ! 250: ! 251: if( (IKOT_IOKIT_CONNECT == type) ! 252: && (client = OSDynamicCast( IOUserClient, obj ))) ! 253: client->clientDied(); ! 254: ! 255: IOMachPort::releasePortForObject( obj, type ); ! 256: ! 257: return( kIOReturnSuccess); ! 258: } ! 259: ! 260: }; /* extern "C" */ ! 261: ! 262: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 263: ! 264: class IOUserNotification : public OSIterator ! 265: { ! 266: OSDeclareDefaultStructors(IOUserNotification) ! 267: ! 268: struct PingMsg { ! 269: mach_msg_header_t msgHdr; ! 270: OSNotificationHeader notifyHeader; ! 271: }; ! 272: ! 273: PingMsg * pingMsg; ! 274: vm_size_t msgSize; ! 275: IONotifier * holdNotify; ! 276: IOLock * lock; ! 277: ! 278: public: ! 279: ! 280: virtual bool init( mach_port_t port, natural_t type, ! 281: OSAsyncReference reference, ! 282: vm_size_t messageSize ); ! 283: virtual void free(); ! 284: ! 285: virtual void setNotification( IONotifier * obj ); ! 286: ! 287: virtual void reset(); ! 288: virtual bool isValid(); ! 289: }; ! 290: ! 291: class IOServiceUserNotification : public IOUserNotification ! 292: { ! 293: OSDeclareDefaultStructors(IOServiceUserNotification) ! 294: ! 295: enum { kMaxOutstanding = 256 }; ! 296: ! 297: OSArray * newSet; ! 298: OSObject * lastEntry; ! 299: bool armed; ! 300: ! 301: public: ! 302: ! 303: virtual bool init( mach_port_t port, natural_t type, ! 304: OSAsyncReference reference ); ! 305: virtual void free(); ! 306: ! 307: static bool _handler( void * target, ! 308: void * ref, IOService * newService ); ! 309: virtual bool handler( void * ref, IOService * newService ); ! 310: ! 311: virtual OSObject * getNextObject(); ! 312: }; ! 313: ! 314: class IOServiceMessageUserNotification : public IOUserNotification ! 315: { ! 316: OSDeclareDefaultStructors(IOServiceMessageUserNotification) ! 317: ! 318: public: ! 319: ! 320: virtual bool init( mach_port_t port, natural_t type, ! 321: OSAsyncReference reference, vm_size_t extraSize ); ! 322: virtual void free(); ! 323: ! 324: static IOReturn _handler( void * target, void * ref, ! 325: UInt32 messageType, IOService * provider, ! 326: void * messageArgument, vm_size_t argSize ); ! 327: virtual IOReturn handler( void * ref, ! 328: UInt32 messageType, IOService * provider, ! 329: void * messageArgument, vm_size_t argSize ); ! 330: ! 331: virtual OSObject * getNextObject(); ! 332: }; ! 333: ! 334: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 335: ! 336: #undef super ! 337: #define super OSIterator ! 338: OSDefineMetaClass( IOUserNotification, OSIterator ) ! 339: OSDefineAbstractStructors( IOUserNotification, OSIterator ) ! 340: ! 341: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 342: ! 343: bool IOUserNotification::init( mach_port_t port, natural_t type, ! 344: OSAsyncReference reference, vm_size_t extraSize ) ! 345: { ! 346: if( !super::init()) ! 347: return( false ); ! 348: ! 349: lock = IOLockAlloc(); ! 350: if( !lock) ! 351: return( false ); ! 352: ! 353: msgSize = sizeof( PingMsg) + extraSize; ! 354: pingMsg = (PingMsg *) IOMalloc( msgSize); ! 355: if( !pingMsg) ! 356: return( false ); ! 357: ! 358: bzero( pingMsg, msgSize); ! 359: ! 360: pingMsg->msgHdr.msgh_remote_port = port; ! 361: pingMsg->msgHdr.msgh_bits = MACH_MSGH_BITS( ! 362: MACH_MSG_TYPE_COPY_SEND, ! 363: MACH_MSG_TYPE_COPY_SEND ); ! 364: pingMsg->msgHdr.msgh_size = msgSize; ! 365: pingMsg->msgHdr.msgh_id = kOSNotificationMessageID; ! 366: ! 367: pingMsg->notifyHeader.size = extraSize; ! 368: pingMsg->notifyHeader.type = type; ! 369: bcopy( reference, pingMsg->notifyHeader.reference, sizeof(OSAsyncReference) ); ! 370: ! 371: return( true ); ! 372: } ! 373: ! 374: void IOUserNotification::free( void ) ! 375: { ! 376: if( holdNotify) ! 377: holdNotify->remove(); ! 378: // can't be in handler now ! 379: ! 380: if( pingMsg) ! 381: IOFree( pingMsg, msgSize); ! 382: ! 383: if( lock) ! 384: IOLockFree( lock ); ! 385: ! 386: super::free(); ! 387: } ! 388: ! 389: ! 390: void IOUserNotification::setNotification( IONotifier * notify ) ! 391: { ! 392: if( holdNotify) ! 393: holdNotify->remove(); ! 394: ! 395: holdNotify = notify; ! 396: } ! 397: ! 398: void IOUserNotification::reset() ! 399: { ! 400: // ? ! 401: } ! 402: ! 403: bool IOUserNotification::isValid() ! 404: { ! 405: return( true ); ! 406: } ! 407: ! 408: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 409: ! 410: #undef super ! 411: #define super IOUserNotification ! 412: OSDefineMetaClassAndStructors(IOServiceUserNotification, IOUserNotification) ! 413: ! 414: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 415: ! 416: bool IOServiceUserNotification::init( mach_port_t port, natural_t type, ! 417: OSAsyncReference reference ) ! 418: { ! 419: newSet = OSArray::withCapacity( 1 ); ! 420: if( !newSet) ! 421: return( false ); ! 422: ! 423: return( super::init( port, type, reference, 0) ); ! 424: } ! 425: ! 426: void IOServiceUserNotification::free( void ) ! 427: { ! 428: if( lastEntry) ! 429: lastEntry->release(); ! 430: ! 431: if( newSet) ! 432: newSet->release(); ! 433: ! 434: super::free(); ! 435: } ! 436: ! 437: bool IOServiceUserNotification::_handler( void * target, ! 438: void * ref, IOService * newService ) ! 439: { ! 440: return( ((IOServiceUserNotification *) target)->handler( ref, newService )); ! 441: } ! 442: ! 443: bool IOServiceUserNotification::handler( void * /* ref */, ! 444: IOService * newService ) ! 445: { ! 446: unsigned int count; ! 447: kern_return_t kr; ! 448: IOMachPort * machPort; ! 449: bool sendPing = false; ! 450: ! 451: IOTakeLock( lock ); ! 452: ! 453: count = newSet->getCount(); ! 454: if( count < kMaxOutstanding) { ! 455: ! 456: newSet->setObject( newService ); ! 457: if( (sendPing = (armed && (0 == count)))) ! 458: armed = false; ! 459: } ! 460: ! 461: IOUnlock( lock ); ! 462: ! 463: if( sendPing) { ! 464: if( (0 == pingMsg->msgHdr.msgh_local_port) ! 465: && (machPort = IOMachPort::portForObject( this, IKOT_IOKIT_OBJECT ) )) ! 466: pingMsg->msgHdr.msgh_local_port = machPort->port; ! 467: ! 468: kr = mach_msg_send_from_kernel( &pingMsg->msgHdr, ! 469: pingMsg->msgHdr.msgh_size); ! 470: if( KERN_SUCCESS != kr) ! 471: IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__, kr ); ! 472: } ! 473: ! 474: return( true ); ! 475: } ! 476: ! 477: OSObject * IOServiceUserNotification::getNextObject() ! 478: { ! 479: unsigned int count; ! 480: OSObject * result; ! 481: ! 482: IOTakeLock( lock ); ! 483: ! 484: if( lastEntry) ! 485: lastEntry->release(); ! 486: ! 487: count = newSet->getCount(); ! 488: if( count ) { ! 489: result = newSet->getObject( count - 1 ); ! 490: result->retain(); ! 491: newSet->removeObject( count - 1); ! 492: } else { ! 493: result = 0; ! 494: armed = true; ! 495: } ! 496: lastEntry = result; ! 497: ! 498: IOUnlock( lock ); ! 499: ! 500: return( result ); ! 501: } ! 502: ! 503: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 504: ! 505: OSDefineMetaClassAndStructors(IOServiceMessageUserNotification, IOUserNotification) ! 506: ! 507: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 508: ! 509: bool IOServiceMessageUserNotification::init( mach_port_t port, natural_t type, ! 510: OSAsyncReference reference, vm_size_t extraSize ) ! 511: { ! 512: return( super::init( port, type, reference, ! 513: sizeof(IOServiceInterestContent) + extraSize) ); ! 514: } ! 515: ! 516: void IOServiceMessageUserNotification::free( void ) ! 517: { ! 518: super::free(); ! 519: } ! 520: ! 521: IOReturn IOServiceMessageUserNotification::_handler( void * target, void * ref, ! 522: UInt32 messageType, IOService * provider, ! 523: void * argument, vm_size_t argSize ) ! 524: { ! 525: return( ((IOServiceMessageUserNotification *) target)->handler( ! 526: ref, messageType, provider, argument, argSize)); ! 527: } ! 528: ! 529: IOReturn IOServiceMessageUserNotification::handler( void * ref, ! 530: UInt32 messageType, IOService * provider, ! 531: void * messageArgument, vm_size_t argSize ) ! 532: { ! 533: kern_return_t kr; ! 534: IOMachPort * machPort; ! 535: IOServiceInterestContent * data = (IOServiceInterestContent *) ! 536: pingMsg->notifyHeader.content; ! 537: ! 538: data->messageType = messageType; ! 539: if( argSize == 0) { ! 540: argSize = sizeof( messageArgument); ! 541: data->messageArgument[0] = messageArgument; ! 542: } else { ! 543: if( argSize > kIOUserNotifyMaxMessageSize) ! 544: argSize = kIOUserNotifyMaxMessageSize; ! 545: bcopy( messageArgument, data->messageArgument, argSize ); ! 546: } ! 547: pingMsg->msgHdr.msgh_size = sizeof( PingMsg) ! 548: + sizeof( IOServiceInterestContent ) ! 549: - sizeof( data->messageArgument) ! 550: + argSize; ! 551: ! 552: if( (machPort = IOMachPort::portForObject( provider, IKOT_IOKIT_OBJECT ) )) ! 553: pingMsg->msgHdr.msgh_local_port = machPort->port; ! 554: else ! 555: pingMsg->msgHdr.msgh_local_port = MACH_PORT_NULL; ! 556: ! 557: kr = mach_msg_send_from_kernel( &pingMsg->msgHdr, ! 558: pingMsg->msgHdr.msgh_size); ! 559: if( KERN_SUCCESS != kr) ! 560: IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__, kr ); ! 561: ! 562: return( kIOReturnSuccess ); ! 563: } ! 564: ! 565: OSObject * IOServiceMessageUserNotification::getNextObject() ! 566: { ! 567: return( 0 ); ! 568: } ! 569: ! 570: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 571: ! 572: #undef super ! 573: #define super IOService ! 574: OSDefineMetaClass( IOUserClient, IOService ) ! 575: OSDefineAbstractStructors( IOUserClient, IOService ) ! 576: ! 577: void IOUserClient::initialize( void ) ! 578: { ! 579: gIOObjectPortLock = IOLockAlloc(); ! 580: ! 581: assert( gIOObjectPortLock ); ! 582: } ! 583: ! 584: IOReturn IOUserClient::clientDied( void ) ! 585: { ! 586: return( clientClose()); ! 587: } ! 588: ! 589: IOReturn IOUserClient::clientClose( void ) ! 590: { ! 591: return( kIOReturnUnsupported ); ! 592: } ! 593: ! 594: IOService * IOUserClient::getService( void ) ! 595: { ! 596: return( 0 ); ! 597: } ! 598: ! 599: IOReturn IOUserClient::registerNotificationPort( ! 600: mach_port_t /* port */, ! 601: UInt32 /* type */, ! 602: UInt32 /* refCon */) ! 603: { ! 604: return( kIOReturnUnsupported); ! 605: } ! 606: ! 607: IOReturn IOUserClient::getNotificationSemaphore( UInt32 notification_type, ! 608: semaphore_t * semaphore ) ! 609: { ! 610: return( kIOReturnUnsupported); ! 611: } ! 612: ! 613: IOReturn IOUserClient::connectClient( IOUserClient * /* client */ ) ! 614: { ! 615: return( kIOReturnUnsupported); ! 616: } ! 617: ! 618: IOReturn IOUserClient::clientMemoryForType( UInt32 type, ! 619: IOOptionBits * options, ! 620: IOMemoryDescriptor ** memory ) ! 621: { ! 622: return( kIOReturnUnsupported); ! 623: } ! 624: ! 625: IOMemoryMap * IOUserClient::mapClientMemory( ! 626: IOOptionBits type, ! 627: task_t task, ! 628: IOOptionBits mapFlags = kIOMapAnywhere, ! 629: IOVirtualAddress atAddress = 0 ) ! 630: { ! 631: IOReturn err; ! 632: IOOptionBits options = 0; ! 633: IOMemoryDescriptor * memory; ! 634: IOMemoryMap * map = 0; ! 635: ! 636: err = clientMemoryForType( (UInt32) type, &options, &memory ); ! 637: ! 638: if( memory && (kIOReturnSuccess == err)) { ! 639: ! 640: options = (options & ~kIOMapUserOptionsMask) ! 641: | (mapFlags & kIOMapUserOptionsMask); ! 642: map = memory->map( task, atAddress, options ); ! 643: memory->release(); ! 644: } ! 645: ! 646: return( map ); ! 647: } ! 648: ! 649: IOExternalMethod * IOUserClient::getExternalMethodForIndex( UInt32 /* index */) ! 650: { ! 651: return( 0 ); ! 652: } ! 653: ! 654: IOExternalAsyncMethod * IOUserClient::getExternalAsyncMethodForIndex( UInt32 /* index */) ! 655: { ! 656: return( 0 ); ! 657: } ! 658: ! 659: IOReturn IOUserClient::sendAsyncResult(OSAsyncReference reference, ! 660: IOReturn result, void *args[], UInt32 numArgs) ! 661: { ! 662: struct ReplyMsg { ! 663: mach_msg_header_t msgHdr; ! 664: OSNotificationHeader notifyHdr; ! 665: IOAsyncCompletionContent asyncContent; ! 666: void * args[kMaxAsyncArgs]; ! 667: }; ! 668: ReplyMsg replyMsg; ! 669: mach_port_t replyPort; ! 670: kern_return_t kr; ! 671: ! 672: // If no reply port, do nothing. ! 673: replyPort = (mach_port_t) reference[0]; ! 674: if(replyPort == MACH_PORT_NULL) ! 675: return kIOReturnSuccess; ! 676: ! 677: if(numArgs > kMaxAsyncArgs) ! 678: return kIOReturnMessageTooLarge; ! 679: replyMsg.msgHdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0); ! 680: replyMsg.msgHdr.msgh_size = ! 681: sizeof(replyMsg) - (kMaxAsyncArgs-numArgs)*sizeof(void *); ! 682: replyMsg.msgHdr.msgh_remote_port = replyPort; ! 683: replyMsg.msgHdr.msgh_local_port = 0; ! 684: replyMsg.msgHdr.msgh_id = kOSNotificationMessageID; ! 685: ! 686: replyMsg.notifyHdr.size = sizeof(IOAsyncCompletionContent) ! 687: + numArgs*sizeof(void *); ! 688: replyMsg.notifyHdr.type = kIOAsyncCompletionNotificationType; ! 689: bcopy( reference, replyMsg.notifyHdr.reference, sizeof(OSAsyncReference)); ! 690: ! 691: replyMsg.asyncContent.result = result; ! 692: if(numArgs > 0) ! 693: bcopy(args, replyMsg.args, sizeof(void *)*numArgs); ! 694: kr = mach_msg_send_from_kernel( &replyMsg.msgHdr, ! 695: replyMsg.msgHdr.msgh_size); ! 696: if( KERN_SUCCESS != kr) ! 697: IOLog("%s: mach_msg_send_from_kernel {%x}\n", __FILE__, kr ); ! 698: return kr; ! 699: } ! 700: ! 701: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 702: ! 703: #include <IOKit/pci/IOPCIDevice.h> ! 704: ! 705: static void makeMatchingCompatible( OSDictionary * dict ) ! 706: { ! 707: const char * key; ! 708: const char * newKey; ! 709: OSObject * value; ! 710: int i = 0; ! 711: ! 712: static const char * gratuitousNameChanges[] = { ! 713: "IOImports", kIOProviderClassKey, ! 714: "IOClass Names", kIOClassKey, ! 715: "IOProbe Score", kIOProbeScoreKey, ! 716: "IOKit Debug", kIOKitDebugKey, ! 717: "IONeededResources", kIOResourceMatchKey, ! 718: "IOName Match", kIONameMatchKey, ! 719: "IOPCI Match", kIOPCIMatchKey, ! 720: "IOPCI Primary Match", kIOPCIPrimaryMatchKey, ! 721: "IOPCI Secondary Match",kIOPCISecondaryMatchKey, ! 722: "IOPCI Class Match", kIOPCIClassMatchKey, ! 723: 0 ! 724: }; ! 725: ! 726: while( (key = gratuitousNameChanges[i++])) { ! 727: newKey = gratuitousNameChanges[i++]; ! 728: if( (value = dict->getObject( key)) ! 729: && (0 == dict->getObject( newKey))) { ! 730: IOLog("Must change soon: %s to %s\n", key, newKey); ! 731: dict->setObject( newKey, value); ! 732: dict->removeObject( key); ! 733: } ! 734: } ! 735: } ! 736: ! 737: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 738: ! 739: extern "C" { ! 740: ! 741: #define CHECK(cls,obj,out) \ ! 742: cls * out; \ ! 743: if( !(out = OSDynamicCast( cls, obj))) \ ! 744: return( kIOReturnBadArgument ) ! 745: ! 746: /* Routine io_object_get_class */ ! 747: kern_return_t is_io_object_get_class( ! 748: io_object_t object, ! 749: io_name_t className ) ! 750: { ! 751: strcpy( className, object->getMetaClass()->getClassName()); ! 752: return( kIOReturnSuccess ); ! 753: } ! 754: ! 755: /* Routine io_object_conforms_to */ ! 756: kern_return_t is_io_object_conforms_to( ! 757: io_object_t object, ! 758: io_name_t className, ! 759: boolean_t *conforms ) ! 760: { ! 761: *conforms = (0 != object->metaCast( className )); ! 762: return( kIOReturnSuccess ); ! 763: } ! 764: ! 765: /* Routine io_object_get_retain_count */ ! 766: kern_return_t is_io_object_get_retain_count( ! 767: io_object_t object, ! 768: int *retainCount ) ! 769: { ! 770: *retainCount = object->getRetainCount(); ! 771: return( kIOReturnSuccess ); ! 772: } ! 773: ! 774: /* Routine io_iterator_next */ ! 775: kern_return_t is_io_iterator_next( ! 776: io_object_t iterator, ! 777: io_object_t *object ) ! 778: { ! 779: OSObject * obj; ! 780: ! 781: CHECK( OSIterator, iterator, iter ); ! 782: ! 783: obj = iter->getNextObject(); ! 784: if( obj) { ! 785: obj->retain(); ! 786: *object = obj; ! 787: return( kIOReturnSuccess ); ! 788: } else ! 789: return( kIOReturnNoDevice ); ! 790: } ! 791: ! 792: /* Routine io_iterator_reset */ ! 793: kern_return_t is_io_iterator_reset( ! 794: io_object_t iterator ) ! 795: { ! 796: CHECK( OSIterator, iterator, iter ); ! 797: ! 798: iter->reset(); ! 799: ! 800: return( kIOReturnSuccess ); ! 801: } ! 802: ! 803: /* Routine io_iterator_is_valid */ ! 804: kern_return_t is_io_iterator_is_valid( ! 805: io_object_t iterator, ! 806: boolean_t *is_valid ) ! 807: { ! 808: CHECK( OSIterator, iterator, iter ); ! 809: ! 810: *is_valid = iter->isValid(); ! 811: ! 812: return( kIOReturnSuccess ); ! 813: } ! 814: ! 815: /* Routine io_service_match_property_table */ ! 816: kern_return_t is_io_service_match_property_table( ! 817: io_service_t _service, ! 818: io_string_t matching, ! 819: boolean_t *matches ) ! 820: { ! 821: CHECK( IOService, _service, service ); ! 822: ! 823: kern_return_t kr; ! 824: OSObject * obj; ! 825: OSDictionary * dict; ! 826: ! 827: obj = OSUnserializeXML( matching ); ! 828: ! 829: if( (dict = OSDynamicCast( OSDictionary, obj))) { ! 830: *matches = service->passiveMatch( dict ); ! 831: kr = kIOReturnSuccess; ! 832: } else ! 833: kr = kIOReturnBadArgument; ! 834: ! 835: if( obj) ! 836: obj->release(); ! 837: ! 838: return( kr ); ! 839: } ! 840: ! 841: /* Routine io_service_get_matching_services */ ! 842: kern_return_t is_io_service_get_matching_services( ! 843: mach_port_t master_port, ! 844: io_string_t matching, ! 845: io_iterator_t *existing ) ! 846: { ! 847: kern_return_t kr; ! 848: OSObject * obj; ! 849: OSDictionary * dict; ! 850: ! 851: if( master_port != master_device_port) ! 852: return( kIOReturnNotPrivileged); ! 853: ! 854: obj = OSUnserializeXML( matching ); ! 855: ! 856: if( (dict = OSDynamicCast( OSDictionary, obj))) { ! 857: makeMatchingCompatible( dict ); // temp for binary compatibility ! 858: *existing = IOService::getMatchingServices( dict ); ! 859: kr = kIOReturnSuccess; ! 860: } else ! 861: kr = kIOReturnBadArgument; ! 862: ! 863: if( obj) ! 864: obj->release(); ! 865: ! 866: return( kr ); ! 867: } ! 868: ! 869: /* Routine io_service_add_notification */ ! 870: kern_return_t is_io_service_add_notification( ! 871: mach_port_t master_port, ! 872: io_name_t notification_type, ! 873: io_string_t matching, ! 874: mach_port_t port, ! 875: io_async_ref_t reference, ! 876: mach_msg_type_number_t referenceCnt, ! 877: io_object_t * notification ) ! 878: { ! 879: ! 880: IOServiceUserNotification * userNotify = 0; ! 881: IONotifier * notify = 0; ! 882: const OSSymbol * sym; ! 883: OSDictionary * dict; ! 884: IOReturn err; ! 885: unsigned long int userMsgType; ! 886: ! 887: ! 888: if( master_port != master_device_port) ! 889: return( kIOReturnNotPrivileged); ! 890: ! 891: do { ! 892: err = kIOReturnNoResources; ! 893: ! 894: if( !(sym = OSSymbol::withCString( notification_type ))) ! 895: err = kIOReturnNoResources; ! 896: ! 897: if( !(dict = OSDynamicCast( OSDictionary, ! 898: OSUnserializeXML( matching )))) { ! 899: err = kIOReturnBadArgument; ! 900: continue; ! 901: } ! 902: makeMatchingCompatible( dict ); // temp for binary compatibility ! 903: ! 904: if( (sym == gIOPublishNotification) ! 905: || (sym == gIOFirstPublishNotification)) ! 906: userMsgType = kIOServicePublishNotificationType; ! 907: else if( (sym == gIOMatchedNotification) ! 908: || (sym == gIOFirstMatchNotification)) ! 909: userMsgType = kIOServiceMatchedNotificationType; ! 910: else if( sym == gIOTerminatedNotification) ! 911: userMsgType = kIOServiceTerminatedNotificationType; ! 912: else ! 913: userMsgType = kLastIOKitNotificationType; ! 914: ! 915: userNotify = new IOServiceUserNotification; ! 916: ! 917: if( userNotify && !userNotify->init( port, userMsgType, ! 918: reference)) { ! 919: userNotify->release(); ! 920: userNotify = 0; ! 921: } ! 922: if( !userNotify) ! 923: continue; ! 924: ! 925: notify = IOService::addNotification( sym, dict, ! 926: &userNotify->_handler, userNotify ); ! 927: if( notify) { ! 928: dict = 0; ! 929: *notification = userNotify; ! 930: userNotify->setNotification( notify ); ! 931: err = kIOReturnSuccess; ! 932: } else ! 933: err = kIOReturnUnsupported; ! 934: ! 935: } while( false ); ! 936: ! 937: if( sym) ! 938: sym->release(); ! 939: if( dict) ! 940: dict->release(); ! 941: ! 942: return( err ); ! 943: } ! 944: ! 945: /* Routine io_service_add_notification_old */ ! 946: kern_return_t is_io_service_add_notification_old( ! 947: mach_port_t master_port, ! 948: io_name_t notification_type, ! 949: io_string_t matching, ! 950: mach_port_t port, ! 951: natural_t ref, ! 952: io_object_t * notification ) ! 953: { ! 954: return( is_io_service_add_notification( master_port, notification_type, ! 955: matching, port, &ref, 1, notification )); ! 956: } ! 957: ! 958: /* Routine io_service_add_message_notification */ ! 959: kern_return_t is_io_service_add_interest_notification( ! 960: io_object_t _service, ! 961: io_name_t type_of_interest, ! 962: mach_port_t port, ! 963: io_async_ref_t reference, ! 964: mach_msg_type_number_t referenceCnt, ! 965: io_object_t * notification ) ! 966: { ! 967: ! 968: IOServiceMessageUserNotification * userNotify = 0; ! 969: IONotifier * notify = 0; ! 970: const OSSymbol * sym; ! 971: IOReturn err; ! 972: ! 973: CHECK( IOService, _service, service ); ! 974: ! 975: err = kIOReturnNoResources; ! 976: if( (sym = OSSymbol::withCString( type_of_interest ))) do { ! 977: ! 978: userNotify = new IOServiceMessageUserNotification; ! 979: ! 980: if( userNotify && !userNotify->init( port, kIOServiceMessageNotificationType, ! 981: reference, kIOUserNotifyMaxMessageSize )) { ! 982: userNotify->release(); ! 983: userNotify = 0; ! 984: } ! 985: if( !userNotify) ! 986: continue; ! 987: ! 988: notify = service->registerInterest( sym, ! 989: &userNotify->_handler, userNotify ); ! 990: if( notify) { ! 991: *notification = userNotify; ! 992: userNotify->setNotification( notify ); ! 993: err = kIOReturnSuccess; ! 994: } else ! 995: err = kIOReturnUnsupported; ! 996: ! 997: } while( false ); ! 998: ! 999: return( err ); ! 1000: } ! 1001: ! 1002: /* Routine io_service_acknowledge_notification */ ! 1003: kern_return_t is_io_service_acknowledge_notification( ! 1004: io_object_t _service, ! 1005: natural_t notify_ref, ! 1006: natural_t response ) ! 1007: { ! 1008: CHECK( IOService, _service, service ); ! 1009: ! 1010: return( service->acknowledgeNotification( (IONotificationRef) notify_ref, ! 1011: (IOOptionBits) response )); ! 1012: ! 1013: } ! 1014: ! 1015: /* Routine io_connect_get_semaphore */ ! 1016: kern_return_t is_io_connect_get_notification_semaphore( ! 1017: io_connect_t connection, ! 1018: natural_t notification_type, ! 1019: semaphore_t *semaphore ) ! 1020: { ! 1021: CHECK( IOUserClient, connection, client ); ! 1022: ! 1023: return( client->getNotificationSemaphore( (UInt32) notification_type, ! 1024: semaphore )); ! 1025: } ! 1026: ! 1027: /* Routine io_registry_get_root_entry */ ! 1028: kern_return_t is_io_registry_get_root_entry( ! 1029: mach_port_t master_port, ! 1030: io_object_t *root ) ! 1031: { ! 1032: IORegistryEntry * entry; ! 1033: ! 1034: if( master_port != master_device_port) ! 1035: return( kIOReturnNotPrivileged); ! 1036: ! 1037: entry = IORegistryEntry::getRegistryRoot(); ! 1038: if( entry) ! 1039: entry->retain(); ! 1040: *root = entry; ! 1041: ! 1042: return( kIOReturnSuccess ); ! 1043: } ! 1044: ! 1045: /* Routine io_registry_create_iterator */ ! 1046: kern_return_t is_io_registry_create_iterator( ! 1047: mach_port_t master_port, ! 1048: io_name_t plane, ! 1049: int options, ! 1050: io_object_t *iterator ) ! 1051: { ! 1052: if( master_port != master_device_port) ! 1053: return( kIOReturnNotPrivileged); ! 1054: ! 1055: *iterator = IORegistryIterator::iterateOver( ! 1056: IORegistryEntry::getPlane( plane ), options ); ! 1057: ! 1058: return( *iterator ? kIOReturnSuccess : kIOReturnBadArgument ); ! 1059: } ! 1060: ! 1061: /* Routine io_registry_entry_create_iterator */ ! 1062: kern_return_t is_io_registry_entry_create_iterator( ! 1063: io_object_t registry_entry, ! 1064: io_name_t plane, ! 1065: int options, ! 1066: io_object_t *iterator ) ! 1067: { ! 1068: CHECK( IORegistryEntry, registry_entry, entry ); ! 1069: ! 1070: *iterator = IORegistryIterator::iterateOver( entry, ! 1071: IORegistryEntry::getPlane( plane ), options ); ! 1072: ! 1073: return( *iterator ? kIOReturnSuccess : kIOReturnBadArgument ); ! 1074: } ! 1075: ! 1076: /* Routine io_registry_iterator_enter */ ! 1077: kern_return_t is_io_registry_iterator_enter_entry( ! 1078: io_object_t iterator ) ! 1079: { ! 1080: CHECK( IORegistryIterator, iterator, iter ); ! 1081: ! 1082: iter->enterEntry(); ! 1083: ! 1084: return( kIOReturnSuccess ); ! 1085: } ! 1086: ! 1087: /* Routine io_registry_iterator_exit */ ! 1088: kern_return_t is_io_registry_iterator_exit_entry( ! 1089: io_object_t iterator ) ! 1090: { ! 1091: bool didIt; ! 1092: ! 1093: CHECK( IORegistryIterator, iterator, iter ); ! 1094: ! 1095: didIt = iter->exitEntry(); ! 1096: ! 1097: return( didIt ? kIOReturnSuccess : kIOReturnNoDevice ); ! 1098: } ! 1099: ! 1100: /* Routine io_registry_entry_from_path */ ! 1101: kern_return_t is_io_registry_entry_from_path( ! 1102: mach_port_t master_port, ! 1103: io_string_t path, ! 1104: io_object_t *registry_entry ) ! 1105: { ! 1106: IORegistryEntry * entry; ! 1107: ! 1108: if( master_port != master_device_port) ! 1109: return( kIOReturnNotPrivileged); ! 1110: ! 1111: entry = IORegistryEntry::fromPath( path ); ! 1112: ! 1113: *registry_entry = entry; ! 1114: ! 1115: return( kIOReturnSuccess ); ! 1116: } ! 1117: ! 1118: /* Routine io_registry_entry_in_plane */ ! 1119: kern_return_t is_io_registry_entry_in_plane( ! 1120: io_object_t registry_entry, ! 1121: io_name_t plane, ! 1122: boolean_t *inPlane ) ! 1123: { ! 1124: CHECK( IORegistryEntry, registry_entry, entry ); ! 1125: ! 1126: *inPlane = entry->inPlane( IORegistryEntry::getPlane( plane )); ! 1127: ! 1128: return( kIOReturnSuccess ); ! 1129: } ! 1130: ! 1131: ! 1132: /* Routine io_registry_entry_get_path */ ! 1133: kern_return_t is_io_registry_entry_get_path( ! 1134: io_object_t registry_entry, ! 1135: io_name_t plane, ! 1136: io_string_t path ) ! 1137: { ! 1138: int length; ! 1139: CHECK( IORegistryEntry, registry_entry, entry ); ! 1140: ! 1141: length = sizeof( io_string_t); ! 1142: if( entry->getPath( path, &length, IORegistryEntry::getPlane( plane ))) ! 1143: return( kIOReturnSuccess ); ! 1144: else ! 1145: return( kIOReturnBadArgument ); ! 1146: } ! 1147: ! 1148: ! 1149: /* Routine io_registry_entry_get_name */ ! 1150: kern_return_t is_io_registry_entry_get_name( ! 1151: io_object_t registry_entry, ! 1152: io_name_t name ) ! 1153: { ! 1154: CHECK( IORegistryEntry, registry_entry, entry ); ! 1155: ! 1156: strncpy( name, entry->getName(), sizeof( io_name_t)); ! 1157: ! 1158: return( kIOReturnSuccess ); ! 1159: } ! 1160: ! 1161: /* Routine io_registry_entry_get_name_in_plane */ ! 1162: kern_return_t is_io_registry_entry_get_name_in_plane( ! 1163: io_object_t registry_entry, ! 1164: io_name_t plane, ! 1165: io_name_t name ) ! 1166: { ! 1167: CHECK( IORegistryEntry, registry_entry, entry ); ! 1168: ! 1169: strncpy( name, entry->getName( IORegistryEntry::getPlane( plane )), ! 1170: sizeof( io_name_t)); ! 1171: ! 1172: return( kIOReturnSuccess ); ! 1173: } ! 1174: ! 1175: // Create a vm_map_copy_t or kalloc'ed data for memory ! 1176: // to be copied out. ipc will free after the copyout. ! 1177: ! 1178: static kern_return_t copyoutkdata( void * data, vm_size_t len, ! 1179: io_buf_ptr_t * buf ) ! 1180: { ! 1181: kern_return_t err; ! 1182: void * kdata; ! 1183: vm_map_copy_t copy; ! 1184: bool ool; ! 1185: ! 1186: ool = (len >= msg_ool_size_small); ! 1187: ! 1188: if( ool ) { ! 1189: ! 1190: err = vm_allocate( kernel_map, (vm_offset_t *) &kdata, len, true ); ! 1191: assert( err == KERN_SUCCESS ); ! 1192: if( err) ! 1193: return( err ); ! 1194: ! 1195: bcopy( data, kdata, len ); ! 1196: ! 1197: err = vm_map_copyin( kernel_map, (vm_offset_t) kdata, len, ! 1198: true /* src_destroy */, ©); ! 1199: ! 1200: assert( err == KERN_SUCCESS ); ! 1201: if( err == KERN_SUCCESS ) ! 1202: *buf = (char *) copy; ! 1203: else ! 1204: vm_deallocate( kernel_map, (vm_offset_t ) kdata, len ); ! 1205: ! 1206: } else { ! 1207: ! 1208: kdata = (void *) kalloc( len ); ! 1209: assert( kdata ); ! 1210: if( kdata) { ! 1211: *buf = (char *) kdata; ! 1212: bcopy( data, kdata, len ); ! 1213: err = kIOReturnSuccess; ! 1214: } else ! 1215: err = kIOReturnNoMemory; ! 1216: } ! 1217: ! 1218: return( err ); ! 1219: } ! 1220: ! 1221: ! 1222: /* Routine io_registry_entry_get_properties */ ! 1223: kern_return_t is_io_registry_entry_get_properties( ! 1224: io_object_t registry_entry, ! 1225: io_buf_ptr_t *properties, ! 1226: mach_msg_type_number_t *propertiesCnt ) ! 1227: { ! 1228: kern_return_t err; ! 1229: vm_size_t len; ! 1230: ! 1231: CHECK( IORegistryEntry, registry_entry, entry ); ! 1232: ! 1233: OSSerialize * s = OSSerialize::withCapacity(4096); ! 1234: ! 1235: if( !s) ! 1236: return( kIOReturnNoMemory ); ! 1237: ! 1238: s->clearText(); ! 1239: ! 1240: if( entry->serializeProperties( s )) { ! 1241: len = s->getLength(); ! 1242: *propertiesCnt = len; ! 1243: err = copyoutkdata( s->text(), len, properties ); ! 1244: ! 1245: } else ! 1246: err = kIOReturnUnsupported; ! 1247: ! 1248: s->release(); ! 1249: ! 1250: return( err ); ! 1251: } ! 1252: ! 1253: /* Routine io_registry_entry_set_properties */ ! 1254: kern_return_t is_io_registry_entry_set_properties ! 1255: ( ! 1256: io_object_t registry_entry, ! 1257: io_buf_ptr_t properties, ! 1258: mach_msg_type_number_t propertiesCnt ! 1259: ) ! 1260: { ! 1261: OSObject * obj; ! 1262: IOReturn err; ! 1263: vm_offset_t data; ! 1264: ! 1265: CHECK( IORegistryEntry, registry_entry, entry ); ! 1266: ! 1267: err = vm_map_copyout( kernel_map, &data, (vm_map_copy_t) properties ); ! 1268: ! 1269: if( KERN_SUCCESS == err) { ! 1270: ! 1271: obj = OSUnserializeXML( (const char *) data ); ! 1272: vm_deallocate( kernel_map, data, propertiesCnt ); ! 1273: ! 1274: if( obj) { ! 1275: err = entry->setProperties( obj ); ! 1276: obj->release(); ! 1277: } else ! 1278: err = kIOReturnBadArgument; ! 1279: } ! 1280: ! 1281: return( err ); ! 1282: } ! 1283: ! 1284: ! 1285: /* Routine io_registry_entry_get_property */ ! 1286: kern_return_t is_io_registry_entry_get_property( ! 1287: io_object_t registry_entry, ! 1288: io_name_t property_name, ! 1289: io_scalar_inband_t buf, ! 1290: mach_msg_type_number_t *dataCnt ) ! 1291: { ! 1292: OSObject * obj; ! 1293: OSData * data; ! 1294: OSString * str; ! 1295: OSBoolean * boo; ! 1296: OSNumber * off; ! 1297: UInt64 offsetBytes; ! 1298: unsigned int len = 0; ! 1299: const void * bytes = 0; ! 1300: IOReturn ret = kIOReturnSuccess; ! 1301: ! 1302: CHECK( IORegistryEntry, registry_entry, entry ); ! 1303: ! 1304: obj = entry->getProperty( property_name ); ! 1305: if( !obj) ! 1306: return( kIOReturnNoResources ); ! 1307: ! 1308: // One day OSData will be a common container base class ! 1309: // until then... ! 1310: if( (data = OSDynamicCast( OSData, obj ))) { ! 1311: len = data->getLength(); ! 1312: bytes = data->getBytesNoCopy(); ! 1313: ! 1314: } else if( (str = OSDynamicCast( OSString, obj ))) { ! 1315: len = str->getLength() + 1; ! 1316: bytes = str->getCStringNoCopy(); ! 1317: ! 1318: } else if( (boo = OSDynamicCast( OSBoolean, obj ))) { ! 1319: len = boo->isTrue() ? sizeof("Yes") : sizeof("No"); ! 1320: bytes = boo->isTrue() ? "Yes" : "No"; ! 1321: ! 1322: } else if( (off = OSDynamicCast( OSNumber, obj ))) { ! 1323: offsetBytes = off->unsigned64BitValue(); ! 1324: len = off->numberOfBytes(); ! 1325: bytes = &offsetBytes; ! 1326: #if __BIG_ENDIAN__ ! 1327: bytes = (const void *) ! 1328: (((UInt32) bytes) + (sizeof( UInt64) - len)); ! 1329: #endif ! 1330: ! 1331: } else ! 1332: ret = kIOReturnBadArgument; ! 1333: ! 1334: if( bytes) { ! 1335: if( *dataCnt < len) ! 1336: ret = kIOReturnIPCError; ! 1337: else { ! 1338: *dataCnt = len; ! 1339: bcopy( bytes, buf, len ); ! 1340: } ! 1341: } ! 1342: ! 1343: return( ret ); ! 1344: } ! 1345: ! 1346: ! 1347: /* Routine io_registry_entry_get_child_iterator */ ! 1348: kern_return_t is_io_registry_entry_get_child_iterator( ! 1349: io_object_t registry_entry, ! 1350: io_name_t plane, ! 1351: io_object_t *iterator ) ! 1352: { ! 1353: CHECK( IORegistryEntry, registry_entry, entry ); ! 1354: ! 1355: *iterator = entry->getChildIterator( ! 1356: IORegistryEntry::getPlane( plane )); ! 1357: ! 1358: return( kIOReturnSuccess ); ! 1359: } ! 1360: ! 1361: /* Routine io_registry_entry_get_parent_iterator */ ! 1362: kern_return_t is_io_registry_entry_get_parent_iterator( ! 1363: io_object_t registry_entry, ! 1364: io_name_t plane, ! 1365: io_object_t *iterator) ! 1366: { ! 1367: CHECK( IORegistryEntry, registry_entry, entry ); ! 1368: ! 1369: *iterator = entry->getParentIterator( ! 1370: IORegistryEntry::getPlane( plane )); ! 1371: ! 1372: return( kIOReturnSuccess ); ! 1373: } ! 1374: ! 1375: /* Routine io_service_get_busy_state */ ! 1376: kern_return_t is_io_service_get_busy_state( ! 1377: io_object_t _service, ! 1378: int *busyState ) ! 1379: { ! 1380: CHECK( IOService, _service, service ); ! 1381: ! 1382: *busyState = service->getBusyState(); ! 1383: ! 1384: return( kIOReturnSuccess ); ! 1385: } ! 1386: ! 1387: /* Routine io_service_wait_quiet */ ! 1388: kern_return_t is_io_service_wait_quiet( ! 1389: io_object_t _service, ! 1390: mach_timespec_t wait_time ) ! 1391: { ! 1392: CHECK( IOService, _service, service ); ! 1393: ! 1394: return( service->waitQuiet( &wait_time )); ! 1395: } ! 1396: ! 1397: /* Routine io_service_request_probe */ ! 1398: kern_return_t is_io_service_request_probe( ! 1399: io_object_t _service, ! 1400: int options ) ! 1401: { ! 1402: CHECK( IOService, _service, service ); ! 1403: ! 1404: return( service->requestProbe( options )); ! 1405: } ! 1406: ! 1407: ! 1408: /* Routine io_service_open */ ! 1409: kern_return_t is_io_service_open( ! 1410: io_object_t _service, ! 1411: task_t owningTask, ! 1412: int connect_type, ! 1413: io_object_t *connection ) ! 1414: { ! 1415: IOUserClient * client; ! 1416: IOReturn err; ! 1417: unsigned int token[2]; ! 1418: ! 1419: CHECK( IOService, _service, service ); ! 1420: ! 1421: err = service->newUserClient( owningTask, token, ! 1422: connect_type, &client ); ! 1423: ! 1424: if( err == kIOReturnSuccess) { ! 1425: assert( OSDynamicCast(IOUserClient, client) ); ! 1426: *connection = client; ! 1427: } ! 1428: ! 1429: return( err); ! 1430: } ! 1431: ! 1432: /* Routine io_service_close */ ! 1433: kern_return_t is_io_service_close( ! 1434: io_object_t connection ) ! 1435: { ! 1436: CHECK( IOUserClient, connection, client ); ! 1437: ! 1438: client->clientClose(); ! 1439: ! 1440: return( kIOReturnSuccess ); ! 1441: } ! 1442: ! 1443: /* Routine io_connect_get_service */ ! 1444: kern_return_t is_io_connect_get_service( ! 1445: io_object_t connection, ! 1446: io_object_t *service ) ! 1447: { ! 1448: IOService * theService; ! 1449: ! 1450: CHECK( IOUserClient, connection, client ); ! 1451: ! 1452: theService = client->getService(); ! 1453: if( theService) ! 1454: theService->retain(); ! 1455: ! 1456: *service = theService; ! 1457: ! 1458: return( theService ? kIOReturnSuccess : kIOReturnUnsupported ); ! 1459: } ! 1460: ! 1461: /* Routine io_connect_set_notification_port */ ! 1462: kern_return_t is_io_connect_set_notification_port( ! 1463: io_object_t connection, ! 1464: int notification_type, ! 1465: mach_port_t port, ! 1466: int reference) ! 1467: { ! 1468: CHECK( IOUserClient, connection, client ); ! 1469: ! 1470: return( client->registerNotificationPort( port, notification_type, ! 1471: reference )); ! 1472: } ! 1473: ! 1474: kern_return_t is_io_connect_map_memory( ! 1475: io_object_t connect, ! 1476: int type, ! 1477: task_t task, ! 1478: vm_address_t * mapAddr, ! 1479: vm_size_t * mapSize, ! 1480: int flags ) ! 1481: { ! 1482: IOReturn err; ! 1483: IOMemoryMap * map; ! 1484: mach_port_name_t name; ! 1485: ! 1486: CHECK( IOUserClient, connect, client ); ! 1487: ! 1488: map = client->mapClientMemory( type, task, flags, *mapAddr ); ! 1489: ! 1490: if( map) { ! 1491: *mapAddr = map->getVirtualAddress(); ! 1492: if( mapSize) ! 1493: *mapSize = map->getLength(); ! 1494: // push a name out to the task owning the map, ! 1495: // so we can clean up maps ! 1496: name = IOMachPort::makeSendRightForTask( task, map, IKOT_IOKIT_OBJECT ); ! 1497: assert( name ); ! 1498: err = kIOReturnSuccess; ! 1499: ! 1500: } else ! 1501: err = kIOReturnBadArgument; ! 1502: ! 1503: return( err ); ! 1504: } ! 1505: ! 1506: /* Routine io_connect_add_client */ ! 1507: kern_return_t is_io_connect_add_client( ! 1508: io_object_t connection, ! 1509: io_object_t connect_to) ! 1510: { ! 1511: CHECK( IOUserClient, connection, client ); ! 1512: CHECK( IOUserClient, connect_to, to ); ! 1513: ! 1514: return( client->connectClient( to ) ); ! 1515: } ! 1516: ! 1517: ! 1518: /* Routine io_connect_set_properties */ ! 1519: kern_return_t is_io_connect_set_properties( ! 1520: io_object_t connection, ! 1521: io_buf_ptr_t properties, ! 1522: mach_msg_type_number_t propertiesCnt ) ! 1523: { ! 1524: return( is_io_registry_entry_set_properties( connection, properties, propertiesCnt )); ! 1525: } ! 1526: ! 1527: ! 1528: /* Routine io_connect_method_scalarI_scalarO */ ! 1529: kern_return_t is_io_connect_method_scalarI_scalarO( ! 1530: io_object_t connect, ! 1531: UInt32 index, ! 1532: void * input[], ! 1533: IOByteCount inputCount, ! 1534: void * output[], ! 1535: IOByteCount * outputCount ) ! 1536: { ! 1537: IOReturn err; ! 1538: IOExternalMethod * method; ! 1539: IOService * object; ! 1540: IOMethod func; ! 1541: ! 1542: CHECK( IOUserClient, connect, client); ! 1543: if( (method = client->getExternalMethodForIndex(index))) { ! 1544: do { ! 1545: err = kIOReturnBadArgument; ! 1546: if( kIOUCScalarIScalarO != (method->flags & kIOUCTypeMask)) ! 1547: continue; ! 1548: if( inputCount != method->count0) ! 1549: continue; ! 1550: if( *outputCount != method->count1) ! 1551: continue; ! 1552: ! 1553: func = method->func; ! 1554: object = method->object; ! 1555: ! 1556: switch( inputCount) { ! 1557: ! 1558: case 6: ! 1559: err = (object->*func)( input[0], input[1], input[2], ! 1560: input[3], input[4], input[5] ); ! 1561: break; ! 1562: case 5: ! 1563: err = (object->*func)( input[0], input[1], input[2], ! 1564: input[3], input[4], ! 1565: &output[0] ); ! 1566: break; ! 1567: case 4: ! 1568: err = (object->*func)( input[0], input[1], input[2], ! 1569: input[3], ! 1570: &output[0], &output[1] ); ! 1571: break; ! 1572: case 3: ! 1573: err = (object->*func)( input[0], input[1], input[2], ! 1574: &output[0], &output[1], &output[2] ); ! 1575: break; ! 1576: case 2: ! 1577: err = (object->*func)( input[0], input[1], ! 1578: &output[0], &output[1], &output[2], ! 1579: &output[3] ); ! 1580: break; ! 1581: case 1: ! 1582: err = (object->*func)( input[0], ! 1583: &output[0], &output[1], &output[2], ! 1584: &output[3], &output[4] ); ! 1585: break; ! 1586: case 0: ! 1587: err = (object->*func)( &output[0], &output[1], &output[2], ! 1588: &output[3], &output[4], &output[5] ); ! 1589: break; ! 1590: ! 1591: default: ! 1592: IOLog("%s: Bad method table\n", client->getName()); ! 1593: } ! 1594: } while( false); ! 1595: ! 1596: } else ! 1597: err = kIOReturnUnsupported; ! 1598: ! 1599: return( err); ! 1600: } ! 1601: ! 1602: /* Routine io_connect_method_scalarI_structureO */ ! 1603: kern_return_t is_io_connect_method_scalarI_structureO( ! 1604: io_object_t connect, ! 1605: UInt32 index, ! 1606: void * input[], ! 1607: IOByteCount inputCount, ! 1608: void * output, ! 1609: IOByteCount * outputCount ) ! 1610: { ! 1611: IOReturn err; ! 1612: IOExternalMethod * method; ! 1613: IOService * object; ! 1614: IOMethod func; ! 1615: ! 1616: CHECK( IOUserClient, connect, client); ! 1617: ! 1618: if( (method = client->getExternalMethodForIndex(index))) { ! 1619: do { ! 1620: err = kIOReturnBadArgument; ! 1621: if( kIOUCScalarIStructO != (method->flags & kIOUCTypeMask)) ! 1622: continue; ! 1623: if( inputCount != method->count0) ! 1624: continue; ! 1625: if( (0xffffffff != method->count1) ! 1626: && (*outputCount != method->count1)) ! 1627: continue; ! 1628: ! 1629: func = method->func; ! 1630: object = method->object; ! 1631: ! 1632: switch( inputCount) { ! 1633: ! 1634: case 5: ! 1635: err = (object->*func)( input[0], input[1], input[2], ! 1636: input[3], input[4], ! 1637: output ); ! 1638: break; ! 1639: case 4: ! 1640: err = (object->*func)( input[0], input[1], input[2], ! 1641: input[3], ! 1642: output, (void *)outputCount ); ! 1643: break; ! 1644: case 3: ! 1645: err = (object->*func)( input[0], input[1], input[2], ! 1646: output, (void *)outputCount, 0 ); ! 1647: break; ! 1648: case 2: ! 1649: err = (object->*func)( input[0], input[1], ! 1650: output, (void *)outputCount, 0, 0 ); ! 1651: break; ! 1652: case 1: ! 1653: err = (object->*func)( input[0], ! 1654: output, (void *)outputCount, 0, 0, 0 ); ! 1655: break; ! 1656: case 0: ! 1657: err = (object->*func)( output, (void *)outputCount, 0, 0, 0, 0 ); ! 1658: break; ! 1659: ! 1660: default: ! 1661: IOLog("%s: Bad method table\n", client->getName()); ! 1662: } ! 1663: } while( false); ! 1664: ! 1665: } else ! 1666: err = kIOReturnUnsupported; ! 1667: ! 1668: return( err); ! 1669: } ! 1670: ! 1671: /* Routine io_connect_method_scalarI_structureI */ ! 1672: kern_return_t is_io_connect_method_scalarI_structureI( ! 1673: io_connect_t connect, ! 1674: UInt32 index, ! 1675: void * input[], ! 1676: IOByteCount inputCount, ! 1677: UInt8 * inputStruct, ! 1678: IOByteCount inputStructCount ) ! 1679: { ! 1680: IOReturn err; ! 1681: IOExternalMethod * method; ! 1682: IOService * object; ! 1683: IOMethod func; ! 1684: ! 1685: CHECK( IOUserClient, connect, client); ! 1686: ! 1687: if( (method = client->getExternalMethodForIndex(index))) { ! 1688: do { ! 1689: err = kIOReturnBadArgument; ! 1690: if( kIOUCScalarIStructI != (method->flags & kIOUCTypeMask)) ! 1691: continue; ! 1692: if( (0xffffffff != method->count0) ! 1693: && (inputCount != method->count0)) ! 1694: continue; ! 1695: if( (0xffffffff != method->count1) ! 1696: && (inputStructCount != method->count1)) ! 1697: continue; ! 1698: ! 1699: func = method->func; ! 1700: object = method->object; ! 1701: ! 1702: switch( inputCount) { ! 1703: ! 1704: case 5: ! 1705: err = (object->*func)( input[0], input[1], input[2], ! 1706: input[3], input[4], ! 1707: inputStruct ); ! 1708: break; ! 1709: case 4: ! 1710: err = (object->*func)( input[0], input[1], input[2], ! 1711: input[3], ! 1712: inputStruct, (void *)inputStructCount ); ! 1713: break; ! 1714: case 3: ! 1715: err = (object->*func)( input[0], input[1], input[2], ! 1716: inputStruct, (void *)inputStructCount, ! 1717: 0 ); ! 1718: break; ! 1719: case 2: ! 1720: err = (object->*func)( input[0], input[1], ! 1721: inputStruct, (void *)inputStructCount, ! 1722: 0, 0 ); ! 1723: break; ! 1724: case 1: ! 1725: err = (object->*func)( input[0], ! 1726: inputStruct, (void *)inputStructCount, ! 1727: 0, 0, 0 ); ! 1728: break; ! 1729: case 0: ! 1730: err = (object->*func)( inputStruct, (void *)inputStructCount, ! 1731: 0, 0, 0, 0 ); ! 1732: break; ! 1733: ! 1734: default: ! 1735: IOLog("%s: Bad method table\n", client->getName()); ! 1736: } ! 1737: } while( false); ! 1738: ! 1739: } else ! 1740: err = kIOReturnUnsupported; ! 1741: ! 1742: return( err); ! 1743: } ! 1744: ! 1745: /* Routine io_connect_method_structureI_structureO */ ! 1746: kern_return_t is_io_connect_method_structureI_structureO( ! 1747: io_object_t connect, ! 1748: UInt32 index, ! 1749: UInt8 * input, ! 1750: IOByteCount inputCount, ! 1751: UInt8 * output, ! 1752: IOByteCount * outputCount ) ! 1753: { ! 1754: IOReturn err; ! 1755: IOExternalMethod * method; ! 1756: IOService * object; ! 1757: IOMethod func; ! 1758: ! 1759: CHECK( IOUserClient, connect, client); ! 1760: ! 1761: if( (method = client->getExternalMethodForIndex(index))) { ! 1762: do { ! 1763: err = kIOReturnBadArgument; ! 1764: if( kIOUCStructIStructO != (method->flags & kIOUCTypeMask)) ! 1765: continue; ! 1766: if( (0xffffffff != method->count0) ! 1767: && (inputCount != method->count0)) ! 1768: continue; ! 1769: if( (0xffffffff != method->count1) ! 1770: && (*outputCount != method->count1)) ! 1771: continue; ! 1772: ! 1773: func = method->func; ! 1774: object = method->object; ! 1775: ! 1776: if( method->count1) { ! 1777: if( method->count0) { ! 1778: err = (object->*func)( input, output, ! 1779: (void *)inputCount, outputCount, 0, 0 ); ! 1780: } else { ! 1781: err = (object->*func)( output, outputCount, 0, 0, 0, 0 ); ! 1782: } ! 1783: } else { ! 1784: err = (object->*func)( input, (void *)inputCount, 0, 0, 0, 0 ); ! 1785: } ! 1786: ! 1787: } while( false); ! 1788: ! 1789: } else ! 1790: err = kIOReturnUnsupported; ! 1791: ! 1792: return( err); ! 1793: } ! 1794: ! 1795: kern_return_t is_io_async_method_scalarI_scalarO( ! 1796: io_object_t connect, ! 1797: mach_port_t wakePort, ! 1798: io_async_ref_t reference, ! 1799: mach_msg_type_number_t referenceCnt, ! 1800: UInt32 index, ! 1801: void * input[], ! 1802: IOByteCount inputCount, ! 1803: void * output[], ! 1804: IOByteCount * outputCount ) ! 1805: { ! 1806: IOReturn err; ! 1807: IOExternalAsyncMethod *method; ! 1808: IOService * object; ! 1809: IOAsyncMethod func; ! 1810: ! 1811: CHECK( IOUserClient, connect, client); ! 1812: if( (method = client->getExternalAsyncMethodForIndex(index))) { ! 1813: do { ! 1814: err = kIOReturnBadArgument; ! 1815: if( kIOUCScalarIScalarO != (method->flags & kIOUCTypeMask)) ! 1816: continue; ! 1817: if( inputCount != method->count0) ! 1818: continue; ! 1819: if( *outputCount != method->count1) ! 1820: continue; ! 1821: ! 1822: reference[0] = (natural_t) wakePort; ! 1823: func = method->func; ! 1824: object = method->object; ! 1825: ! 1826: switch( inputCount) { ! 1827: ! 1828: case 6: ! 1829: err = (object->*func)( reference, ! 1830: input[0], input[1], input[2], ! 1831: input[3], input[4], input[5] ); ! 1832: break; ! 1833: case 5: ! 1834: err = (object->*func)( reference, ! 1835: input[0], input[1], input[2], ! 1836: input[3], input[4], ! 1837: &output[0] ); ! 1838: break; ! 1839: case 4: ! 1840: err = (object->*func)( reference, ! 1841: input[0], input[1], input[2], ! 1842: input[3], ! 1843: &output[0], &output[1] ); ! 1844: break; ! 1845: case 3: ! 1846: err = (object->*func)( reference, ! 1847: input[0], input[1], input[2], ! 1848: &output[0], &output[1], &output[2] ); ! 1849: break; ! 1850: case 2: ! 1851: err = (object->*func)( reference, ! 1852: input[0], input[1], ! 1853: &output[0], &output[1], &output[2], ! 1854: &output[3] ); ! 1855: break; ! 1856: case 1: ! 1857: err = (object->*func)( reference, ! 1858: input[0], ! 1859: &output[0], &output[1], &output[2], ! 1860: &output[3], &output[4] ); ! 1861: break; ! 1862: case 0: ! 1863: err = (object->*func)( reference, ! 1864: &output[0], &output[1], &output[2], ! 1865: &output[3], &output[4], &output[5] ); ! 1866: break; ! 1867: ! 1868: default: ! 1869: IOLog("%s: Bad method table\n", client->getName()); ! 1870: } ! 1871: } while( false); ! 1872: ! 1873: } else ! 1874: err = kIOReturnUnsupported; ! 1875: ! 1876: return( err); ! 1877: } ! 1878: ! 1879: kern_return_t is_io_async_method_scalarI_structureO( ! 1880: io_object_t connect, ! 1881: mach_port_t wakePort, ! 1882: io_async_ref_t reference, ! 1883: mach_msg_type_number_t referenceCnt, ! 1884: UInt32 index, ! 1885: void * input[], ! 1886: IOByteCount inputCount, ! 1887: void * output, ! 1888: IOByteCount * outputCount ) ! 1889: { ! 1890: IOReturn err; ! 1891: IOExternalAsyncMethod *method; ! 1892: IOService * object; ! 1893: IOAsyncMethod func; ! 1894: ! 1895: CHECK( IOUserClient, connect, client); ! 1896: ! 1897: if( (method = client->getExternalAsyncMethodForIndex(index))) { ! 1898: do { ! 1899: err = kIOReturnBadArgument; ! 1900: if( kIOUCScalarIStructO != (method->flags & kIOUCTypeMask)) ! 1901: continue; ! 1902: if( inputCount != method->count0) ! 1903: continue; ! 1904: if( (0xffffffff != method->count1) ! 1905: && (*outputCount != method->count1)) ! 1906: continue; ! 1907: ! 1908: reference[0] = (natural_t) wakePort; ! 1909: func = method->func; ! 1910: object = method->object; ! 1911: ! 1912: switch( inputCount) { ! 1913: ! 1914: case 5: ! 1915: err = (object->*func)( reference, ! 1916: input[0], input[1], input[2], ! 1917: input[3], input[4], ! 1918: output ); ! 1919: break; ! 1920: case 4: ! 1921: err = (object->*func)( reference, ! 1922: input[0], input[1], input[2], ! 1923: input[3], ! 1924: output, (void *)outputCount ); ! 1925: break; ! 1926: case 3: ! 1927: err = (object->*func)( reference, ! 1928: input[0], input[1], input[2], ! 1929: output, (void *)outputCount, 0 ); ! 1930: break; ! 1931: case 2: ! 1932: err = (object->*func)( reference, ! 1933: input[0], input[1], ! 1934: output, (void *)outputCount, 0, 0 ); ! 1935: break; ! 1936: case 1: ! 1937: err = (object->*func)( reference, ! 1938: input[0], ! 1939: output, (void *)outputCount, 0, 0, 0 ); ! 1940: break; ! 1941: case 0: ! 1942: err = (object->*func)( reference, ! 1943: output, (void *)outputCount, 0, 0, 0, 0 ); ! 1944: break; ! 1945: ! 1946: default: ! 1947: IOLog("%s: Bad method table\n", client->getName()); ! 1948: } ! 1949: } while( false); ! 1950: ! 1951: } else ! 1952: err = kIOReturnUnsupported; ! 1953: ! 1954: return( err); ! 1955: } ! 1956: ! 1957: kern_return_t is_io_async_method_scalarI_structureI( ! 1958: io_connect_t connect, ! 1959: mach_port_t wakePort, ! 1960: io_async_ref_t reference, ! 1961: mach_msg_type_number_t referenceCnt, ! 1962: UInt32 index, ! 1963: void * input[], ! 1964: IOByteCount inputCount, ! 1965: UInt8 * inputStruct, ! 1966: IOByteCount inputStructCount ) ! 1967: { ! 1968: IOReturn err; ! 1969: IOExternalAsyncMethod *method; ! 1970: IOService * object; ! 1971: IOAsyncMethod func; ! 1972: ! 1973: CHECK( IOUserClient, connect, client); ! 1974: ! 1975: if( (method = client->getExternalAsyncMethodForIndex(index))) { ! 1976: do { ! 1977: err = kIOReturnBadArgument; ! 1978: if( kIOUCScalarIStructI != (method->flags & kIOUCTypeMask)) ! 1979: continue; ! 1980: if( (0xffffffff != method->count0) ! 1981: && (inputCount != method->count0)) ! 1982: continue; ! 1983: if( (0xffffffff != method->count1) ! 1984: && (inputStructCount != method->count1)) ! 1985: continue; ! 1986: ! 1987: reference[0] = (natural_t) wakePort; ! 1988: func = method->func; ! 1989: object = method->object; ! 1990: ! 1991: switch( inputCount) { ! 1992: ! 1993: case 5: ! 1994: err = (object->*func)( reference, ! 1995: input[0], input[1], input[2], ! 1996: input[3], input[4], ! 1997: inputStruct ); ! 1998: break; ! 1999: case 4: ! 2000: err = (object->*func)( reference, ! 2001: input[0], input[1], input[2], ! 2002: input[3], ! 2003: inputStruct, (void *)inputStructCount ); ! 2004: break; ! 2005: case 3: ! 2006: err = (object->*func)( reference, ! 2007: input[0], input[1], input[2], ! 2008: inputStruct, (void *)inputStructCount, ! 2009: 0 ); ! 2010: break; ! 2011: case 2: ! 2012: err = (object->*func)( reference, ! 2013: input[0], input[1], ! 2014: inputStruct, (void *)inputStructCount, ! 2015: 0, 0 ); ! 2016: break; ! 2017: case 1: ! 2018: err = (object->*func)( reference, ! 2019: input[0], ! 2020: inputStruct, (void *)inputStructCount, ! 2021: 0, 0, 0 ); ! 2022: break; ! 2023: case 0: ! 2024: err = (object->*func)( reference, ! 2025: inputStruct, (void *)inputStructCount, ! 2026: 0, 0, 0, 0 ); ! 2027: break; ! 2028: ! 2029: default: ! 2030: IOLog("%s: Bad method table\n", client->getName()); ! 2031: } ! 2032: } while( false); ! 2033: ! 2034: } else ! 2035: err = kIOReturnUnsupported; ! 2036: ! 2037: return( err); ! 2038: } ! 2039: ! 2040: kern_return_t is_io_async_method_structureI_structureO( ! 2041: io_object_t connect, ! 2042: mach_port_t wakePort, ! 2043: io_async_ref_t reference, ! 2044: mach_msg_type_number_t referenceCnt, ! 2045: UInt32 index, ! 2046: UInt8 * input, ! 2047: IOByteCount inputCount, ! 2048: UInt8 * output, ! 2049: IOByteCount * outputCount ) ! 2050: { ! 2051: IOReturn err; ! 2052: IOExternalAsyncMethod *method; ! 2053: IOService * object; ! 2054: IOAsyncMethod func; ! 2055: ! 2056: CHECK( IOUserClient, connect, client); ! 2057: ! 2058: if( (method = client->getExternalAsyncMethodForIndex(index))) { ! 2059: do { ! 2060: err = kIOReturnBadArgument; ! 2061: if( kIOUCStructIStructO != (method->flags & kIOUCTypeMask)) ! 2062: continue; ! 2063: if( (0xffffffff != method->count0) ! 2064: && (inputCount != method->count0)) ! 2065: continue; ! 2066: if( (0xffffffff != method->count1) ! 2067: && (*outputCount != method->count1)) ! 2068: continue; ! 2069: ! 2070: reference[0] = (natural_t) wakePort; ! 2071: func = method->func; ! 2072: object = method->object; ! 2073: ! 2074: if( method->count1) { ! 2075: if( method->count0) { ! 2076: err = (object->*func)( reference, ! 2077: input, output, ! 2078: (void *)inputCount, outputCount, 0, 0 ); ! 2079: } else { ! 2080: err = (object->*func)( reference, ! 2081: output, outputCount, 0, 0, 0, 0 ); ! 2082: } ! 2083: } else { ! 2084: err = (object->*func)( reference, ! 2085: input, (void *)inputCount, 0, 0, 0, 0 ); ! 2086: } ! 2087: ! 2088: } while( false); ! 2089: ! 2090: } else ! 2091: err = kIOReturnUnsupported; ! 2092: ! 2093: return( err); ! 2094: } ! 2095: /* Routine io_make_matching */ ! 2096: kern_return_t is_io_make_matching( ! 2097: mach_port_t master_port, ! 2098: UInt32 type, ! 2099: IOOptionBits options, ! 2100: UInt8 * input, ! 2101: IOByteCount inputCount, ! 2102: io_string_t matching ) ! 2103: { ! 2104: OSSerialize * s; ! 2105: IOReturn err = kIOReturnSuccess; ! 2106: OSDictionary * dict; ! 2107: ! 2108: if( master_port != master_device_port) ! 2109: return( kIOReturnNotPrivileged); ! 2110: ! 2111: switch( type) { ! 2112: ! 2113: case kIOServiceMatching: ! 2114: dict = IOService::serviceMatching( gIOServiceKey ); ! 2115: break; ! 2116: ! 2117: case kIOBSDNameMatching: ! 2118: dict = IOBSDNameMatching( (const char *) input ); ! 2119: break; ! 2120: ! 2121: case kIOOFPathMatching: ! 2122: /* need to look up path, get device type, ! 2123: call matching help based on device type */ ! 2124: dict = IODiskMatching( (const char *) input, ! 2125: matching, sizeof( io_string_t)); ! 2126: break; ! 2127: ! 2128: default: ! 2129: dict = 0; ! 2130: } ! 2131: ! 2132: if( !dict) ! 2133: return( kIOReturnUnsupported); ! 2134: ! 2135: do { ! 2136: s = OSSerialize::withCapacity(4096); ! 2137: if( !s) { ! 2138: err = kIOReturnNoMemory; ! 2139: continue; ! 2140: } ! 2141: s->clearText(); ! 2142: if( !dict->serialize( s )) { ! 2143: err = kIOReturnUnsupported; ! 2144: continue; ! 2145: } ! 2146: ! 2147: if( s->getLength() > sizeof( io_string_t)) { ! 2148: err = kIOReturnNoMemory; ! 2149: continue; ! 2150: } else ! 2151: strcpy( matching, s->text()); ! 2152: ! 2153: } while( false); ! 2154: ! 2155: if( s) ! 2156: s->release(); ! 2157: if( dict) ! 2158: dict->release(); ! 2159: ! 2160: return( err); ! 2161: } ! 2162: ! 2163: /* Routine io_catalog_send_data */ ! 2164: kern_return_t is_io_catalog_send_data( ! 2165: mach_port_t master_port, ! 2166: int flag, ! 2167: io_buf_ptr_t inData, ! 2168: mach_msg_type_number_t inDataCount ! 2169: ) ! 2170: { ! 2171: OSObject * obj = 0; ! 2172: vm_offset_t data; ! 2173: kern_return_t kr = kIOReturnSuccess; ! 2174: ! 2175: //printf("io_catalog_send_data called. flag: %d\n", flag); ! 2176: ! 2177: if( master_port != master_device_port) ! 2178: return kIOReturnNotPrivileged; ! 2179: ! 2180: if ( !inData || !inDataCount ) ! 2181: return kIOReturnBadArgument; ! 2182: ! 2183: kr = vm_map_copyout( kernel_map, &data, (vm_map_copy_t)inData ); ! 2184: if ( kr != kIOReturnSuccess ) ! 2185: return kr; ! 2186: ! 2187: if ( inDataCount ) { ! 2188: obj = (OSObject *)OSUnserializeXML((const char *)data); ! 2189: vm_deallocate( kernel_map, data, inDataCount ); ! 2190: if ( !obj ) ! 2191: return kIOReturnNoMemory; ! 2192: } ! 2193: ! 2194: switch ( flag ) { ! 2195: case kIOCatalogAddDrivers: ! 2196: case kIOCatalogAddDriversNoMatch: { ! 2197: OSArray * array; ! 2198: ! 2199: array = OSDynamicCast(OSArray, obj); ! 2200: if ( array ) { ! 2201: //-- ! 2202: OSDictionary * dict; ! 2203: int i = 0; ! 2204: while( (dict = OSDynamicCast(OSDictionary, array->getObject(i++)))) ! 2205: makeMatchingCompatible( dict ); ! 2206: //-- ! 2207: if ( !gIOCatalogue->addDrivers( array , ! 2208: flag == kIOCatalogAddDrivers) ) { ! 2209: kr = kIOReturnError; ! 2210: } ! 2211: } ! 2212: else { ! 2213: kr = kIOReturnBadArgument; ! 2214: } ! 2215: } ! 2216: break; ! 2217: ! 2218: case kIOCatalogRemoveDrivers: ! 2219: case kIOCatalogRemoveDriversNoMatch: { ! 2220: OSDictionary * dict; ! 2221: ! 2222: dict = OSDynamicCast(OSDictionary, obj); ! 2223: if ( dict ) { ! 2224: makeMatchingCompatible( dict ); ! 2225: if ( !gIOCatalogue->removeDrivers( dict, ! 2226: flag == kIOCatalogRemoveDrivers ) ) { ! 2227: kr = kIOReturnError; ! 2228: } ! 2229: } ! 2230: else { ! 2231: kr = kIOReturnBadArgument; ! 2232: } ! 2233: } ! 2234: break; ! 2235: ! 2236: case kIOCatalogStartMatching: { ! 2237: OSDictionary * dict; ! 2238: ! 2239: dict = OSDynamicCast(OSDictionary, obj); ! 2240: if ( dict ) { ! 2241: makeMatchingCompatible( dict ); ! 2242: if ( !gIOCatalogue->startMatching( dict ) ) { ! 2243: kr = kIOReturnError; ! 2244: } ! 2245: } ! 2246: else { ! 2247: kr = kIOReturnBadArgument; ! 2248: } ! 2249: } ! 2250: break; ! 2251: ! 2252: default: ! 2253: kr = kIOReturnBadArgument; ! 2254: break; ! 2255: } ! 2256: obj->release(); ! 2257: ! 2258: return kr; ! 2259: } ! 2260: ! 2261: /* Routine io_catalog_terminate */ ! 2262: kern_return_t is_io_catalog_terminate( ! 2263: mach_port_t master_port, ! 2264: int flag, ! 2265: io_name_t name ) ! 2266: { ! 2267: kern_return_t kr; ! 2268: ! 2269: if( master_port != master_device_port ) ! 2270: return kIOReturnNotPrivileged; ! 2271: ! 2272: kr = kIOReturnSuccess; ! 2273: switch ( flag ) { ! 2274: case kIOCatalogServiceTerminate: ! 2275: OSIterator * iter; ! 2276: IOService * service; ! 2277: ! 2278: iter = IORegistryIterator::iterateOver(gIOServicePlane, ! 2279: kIORegistryIterateRecursively); ! 2280: if ( !iter ) ! 2281: return kIOReturnNoMemory; ! 2282: ! 2283: do { ! 2284: iter->reset(); ! 2285: while( (service = (IOService *)iter->getNextObject()) ) { ! 2286: if( service->metaCast(name)) { ! 2287: if ( !service->terminate(kIOServiceRequired) ) { ! 2288: kr = kIOReturnUnsupported; ! 2289: break; ! 2290: } ! 2291: } ! 2292: } ! 2293: } while( !service && !iter->isValid()); ! 2294: iter->release(); ! 2295: break; ! 2296: ! 2297: case kIOCatalogModuleUnload: ! 2298: case kIOCatalogModuleTerminate: ! 2299: kr = gIOCatalogue->terminateDriversForModule(name, ! 2300: flag == kIOCatalogModuleUnload); ! 2301: break; ! 2302: ! 2303: default: ! 2304: kr = kIOReturnBadArgument; ! 2305: break; ! 2306: } ! 2307: ! 2308: return( kr ); ! 2309: } ! 2310: ! 2311: /* Routine io_catalog_get_data */ ! 2312: kern_return_t is_io_catalog_get_data( ! 2313: mach_port_t master_port, ! 2314: int flag, ! 2315: io_buf_ptr_t *outData, ! 2316: mach_msg_type_number_t *outDataCount) ! 2317: { ! 2318: kern_return_t kr = kIOReturnSuccess; ! 2319: OSSerialize * s; ! 2320: ! 2321: if( master_port != master_device_port) ! 2322: return kIOReturnNotPrivileged; ! 2323: ! 2324: //printf("io_catalog_get_data called. flag: %d\n", flag); ! 2325: ! 2326: s = OSSerialize::withCapacity(4096); ! 2327: if ( !s ) ! 2328: return kIOReturnNoMemory; ! 2329: ! 2330: s->clearText(); ! 2331: switch ( flag ) { ! 2332: case kIOCatalogGetContents: ! 2333: if ( !gIOCatalogue->serialize(s) ) { ! 2334: kr = kIOReturnNoMemory; ! 2335: } ! 2336: break; ! 2337: ! 2338: default: ! 2339: kr = kIOReturnBadArgument; ! 2340: break; ! 2341: } ! 2342: ! 2343: if ( kr == kIOReturnSuccess ) { ! 2344: vm_offset_t data; ! 2345: vm_map_copy_t copy; ! 2346: vm_size_t size; ! 2347: ! 2348: size = s->getLength(); ! 2349: kr = vm_allocate(kernel_map, &data, size, true); ! 2350: if ( kr == kIOReturnSuccess ) { ! 2351: bcopy(s->text(), (void *)data, size); ! 2352: kr = vm_map_copyin(kernel_map, data, size, true, ©); ! 2353: *outData = (char *)copy; ! 2354: *outDataCount = size; ! 2355: } ! 2356: } ! 2357: ! 2358: s->release(); ! 2359: ! 2360: return kr; ! 2361: } ! 2362: ! 2363: /* Routine io_catalog_get_gen_count */ ! 2364: kern_return_t is_io_catalog_get_gen_count( ! 2365: mach_port_t master_port, ! 2366: int *genCount) ! 2367: { ! 2368: if( master_port != master_device_port) ! 2369: return kIOReturnNotPrivileged; ! 2370: ! 2371: //printf("io_catalog_get_gen_count called.\n"); ! 2372: ! 2373: if ( !genCount ) ! 2374: return kIOReturnBadArgument; ! 2375: ! 2376: *genCount = gIOCatalogue->getGenerationCount(); ! 2377: ! 2378: return kIOReturnSuccess; ! 2379: } ! 2380: ! 2381: /* Routine io_catalog_module_loaded */ ! 2382: kern_return_t is_io_catalog_module_loaded( ! 2383: mach_port_t master_port, ! 2384: io_name_t name) ! 2385: { ! 2386: if( master_port != master_device_port) ! 2387: return kIOReturnNotPrivileged; ! 2388: ! 2389: //printf("io_catalog_module_loaded called. name %s\n", name); ! 2390: ! 2391: if ( !name ) ! 2392: return kIOReturnBadArgument; ! 2393: ! 2394: gIOCatalogue->moduleHasLoaded(name); ! 2395: ! 2396: return kIOReturnSuccess; ! 2397: } ! 2398: ! 2399: kern_return_t is_io_catalog_reset( ! 2400: mach_port_t master_port, ! 2401: int flag) ! 2402: { ! 2403: if( master_port != master_device_port) ! 2404: return kIOReturnNotPrivileged; ! 2405: ! 2406: switch ( flag ) { ! 2407: case kIOCatalogResetDefault: ! 2408: gIOCatalogue->reset(); ! 2409: break; ! 2410: ! 2411: default: ! 2412: return kIOReturnBadArgument; ! 2413: } ! 2414: ! 2415: return kIOReturnSuccess; ! 2416: } ! 2417: ! 2418: }; /* extern "C" */ ! 2419: ! 2420:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.