1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1999-2013 Apple Computer, Inc. All Rights Reserved. 6 * 7 * This file contains Original Code and/or Modifications of Original Code 8 * as defined in and that are subject to the Apple Public Source License 9 * Version 2.0 (the 'License'). You may not use this file except in 10 * compliance with the License. Please obtain a copy of the License at 11 * http://www.opensource.apple.com/apsl/ and read it before using this 12 * file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 * Please see the License for the specific language governing rights and 20 * limitations under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24 25#include <TargetConditionals.h> 26 27#include <IOKit/IOLib.h> // IOMalloc/IOFree 28#include <IOKit/IOBufferMemoryDescriptor.h> 29#include <IOKit/hidsystem/IOHIDSystem.h> 30#include <IOKit/IOEventSource.h> 31#include <IOKit/IOMessage.h> 32 33#include "IOHIDFamilyPrivate.h" 34#include "IOHIDDevice.h" 35#include "IOHIDElementPrivate.h" 36#include "IOHIDParserPriv.h" 37#include "IOHIDInterface.h" 38#include "IOHIDPrivateKeys.h" 39#include "IOHIDFamilyPrivate.h" 40#include "IOHIDLibUserClient.h" 41#include "IOHIDFamilyTrace.h" 42#include "OSStackRetain.h" 43 44#include <sys/queue.h> 45#include <machine/limits.h> 46 47#if !TARGET_OS_EMBEDDED 48#include "IOHIKeyboard.h" 49#include "IOHIPointing.h" 50#endif 51 52//=========================================================================== 53// IOHIDAsyncReportQueue class 54 55class IOHIDAsyncReportQueue : public IOEventSource 56{ 57 OSDeclareDefaultStructors( IOHIDAsyncReportQueue ) 58 59 struct AsyncReportEntry { 60 queue_chain_t chain; 61 62 AbsoluteTime timeStamp; 63 uint8_t * reportData; 64 size_t reportLength; 65 IOHIDReportType reportType; 66 IOOptionBits options; 67 UInt32 completionTimeout; 68 IOHIDCompletion completion; 69 }; 70 71 IOLock * fQueueLock; 72 queue_head_t fQueueHead; 73 74public: 75 static IOHIDAsyncReportQueue *withOwner(IOHIDDevice *inOwner); 76 77 virtual bool init(IOHIDDevice *owner); 78 79 virtual bool checkForWork(); 80 81 virtual IOReturn postReport(AbsoluteTime timeStamp, 82 IOMemoryDescriptor * report, 83 IOHIDReportType reportType, 84 IOOptionBits options, 85 UInt32 completionTimeout, 86 IOHIDCompletion * completion); 87}; 88 89OSDefineMetaClassAndStructors( IOHIDAsyncReportQueue, IOEventSource ) 90 91//--------------------------------------------------------------------------- 92IOHIDAsyncReportQueue *IOHIDAsyncReportQueue::withOwner(IOHIDDevice *inOwner) 93{ 94 IOHIDAsyncReportQueue *es = NULL; 95 bool result = false; 96 97 es = OSTypeAlloc( IOHIDAsyncReportQueue ); 98 if (es) { 99 result = es->init( inOwner/*, inAction*/ ); 100 101 if (!result) { 102 es->release(); 103 es = NULL; 104 } 105 106 } 107 108 return es; 109} 110 111//--------------------------------------------------------------------------- 112bool IOHIDAsyncReportQueue::init(IOHIDDevice *owner_I) 113{ 114 queue_init( &fQueueHead ); 115 fQueueLock = IOLockAlloc(); 116 return IOEventSource::init(owner_I/*, action*/); 117} 118 119//--------------------------------------------------------------------------- 120bool IOHIDAsyncReportQueue::checkForWork() 121{ 122 bool moreToDo = false; 123 124 IOLockLock(fQueueLock); 125 if (!queue_empty(&fQueueHead)) { 126 127 AsyncReportEntry *entry = NULL; 128 queue_remove_first(&fQueueHead, entry, AsyncReportEntry *, chain); 129 130 if (entry) { 131 IOLockUnlock(fQueueLock); 132 133 IOReturn status; 134 135 IOMemoryDescriptor *md = IOMemoryDescriptor::withAddress(entry->reportData, entry->reportLength, kIODirectionOut); 136 137 if (md) { 138 md->prepare(); 139 140 status = ((IOHIDDevice *)owner)->handleReportWithTime(entry->timeStamp, md, entry->reportType, entry->options); 141 142 md->complete(); 143 144 md->release(); 145 146 if (entry->completion.action) { 147 (entry->completion.action)(entry->completion.target, entry->completion.parameter, status, 0); 148 } 149 } 150 151 IOFree(entry->reportData, entry->reportLength); 152 IODelete(entry, AsyncReportEntry, 1); 153 154 IOLockLock(fQueueLock); 155 } 156 } 157 158 moreToDo = (!queue_empty(&fQueueHead)); 159 IOLockUnlock(fQueueLock); 160 161 return moreToDo; 162} 163 164//--------------------------------------------------------------------------- 165IOReturn IOHIDAsyncReportQueue::postReport( 166 AbsoluteTime timeStamp, 167 IOMemoryDescriptor * report, 168 IOHIDReportType reportType, 169 IOOptionBits options, 170 UInt32 completionTimeout, 171 IOHIDCompletion * completion) 172{ 173 AsyncReportEntry *entry; 174 175 entry = IONew(AsyncReportEntry, 1); 176 if (!entry) 177 return kIOReturnError; 178 179 bzero(entry, sizeof(AsyncReportEntry)); 180 181 entry->timeStamp = timeStamp; 182 183 entry->reportLength = report->getLength(); 184 entry->reportData = (uint8_t *)IOMalloc(entry->reportLength); 185 186 if (entry->reportData) { 187 report->readBytes(0, entry->reportData, entry->reportLength); 188 189 entry->reportType = reportType; 190 entry->options = options; 191 entry->completionTimeout = completionTimeout; 192 193 if (completion) 194 entry->completion = *completion; 195 196 IOLockLock(fQueueLock); 197 queue_enter(&fQueueHead, entry, AsyncReportEntry *, chain); 198 IOLockUnlock(fQueueLock); 199 200 signalWorkAvailable(); 201 } else { 202 IODelete(entry, AsyncReportEntry, 1); 203 } 204 205 return kIOReturnSuccess; 206} 207 208//=========================================================================== 209// IOHIDDevice class 210 211#undef super 212#define super IOService 213 214OSDefineMetaClassAndAbstractStructors( IOHIDDevice, IOService ) 215 216// RESERVED IOHIDDevice CLASS VARIABLES 217// Defined here to avoid conflicts from within header file 218#define _clientSet _reserved->clientSet 219#define _seizedClient _reserved->seizedClient 220#define _eventDeadline _reserved->eventDeadline 221#define _inputInterruptElementArray _reserved->inputInterruptElementArray 222#define _performTickle _reserved->performTickle 223#define _performWakeTickle _reserved->performWakeTickle 224#define _interfaceNub _reserved->interfaceNub 225#define _rollOverElement _reserved->rollOverElement 226#define _hierarchElements _reserved->hierarchElements 227#define _asyncReportQueue _reserved->asyncReportQueue 228 229#define kIOHIDEventThreshold 10 230 231// Number of slots in the report handler dispatch table. 232// 233#define kReportHandlerSlots 8 234 235// Convert from a report ID to a dispatch table slot index. 236// 237#define GetReportHandlerSlot(id) ((id) & (kReportHandlerSlots - 1)) 238 239#define GetElement(index) \ 240 (IOHIDElementPrivate *) _elementArray->getObject((UInt32)index) 241 242// Serialize access to the elements for report handling, 243// event queueing, and report creation. 244// 245#define ELEMENT_LOCK IORecursiveLockLock( _elementLock ) 246#define ELEMENT_UNLOCK IORecursiveLockUnlock( _elementLock ) 247 248// Describes the handler(s) at each report dispatch table slot. 249// 250struct IOHIDReportHandler 251{ 252 IOHIDElementPrivate * head[ kIOHIDReportTypeCount ]; 253}; 254 255#define GetHeadElement(slot, type) _reportHandlers[slot].head[type] 256 257// #define DEBUG 1 258#ifdef DEBUG 259#define DLOG(fmt, args...) IOLog(fmt, args) 260#else 261#define DLOG(fmt, args...) 262#endif 263 264#ifndef kIOUserClientCrossEndianKey 265#define kIOUserClientCrossEndianKey "IOUserClientCrossEndian" 266#endif 267 268#ifndef kIOUserClientCrossEndianCompatibleKey 269#define kIOUserClientCrossEndianCompatibleKey "IOUserClientCrossEndianCompatible" 270#endif 271 272// *** GAME DEVICE HACK *** 273static SInt32 g3DGameControllerCount = 0; 274// *** END GAME DEVICE HACK *** 275 276static IONotifier *gDeviceMatchedNotifier = 0; 277 278//--------------------------------------------------------------------------- 279// Initialize an IOHIDDevice object. 280 281bool IOHIDDevice::init( OSDictionary * dict ) 282{ 283 _reserved = IONew( ExpansionData, 1 ); 284 285 if (!_reserved) 286 return false; 287 288 bzero(_reserved, sizeof(ExpansionData)); 289 290 // Create an OSSet to store client objects. Initial capacity 291 // (which can grow) is set at 2 clients. 292 293 _clientSet = OSSet::withCapacity(2); 294 if ( _clientSet == 0 ) 295 return false; 296 297 return super::init(dict); 298} 299 300//--------------------------------------------------------------------------- 301// Free an IOHIDDevice object after its retain count drops to zero. 302// Release all resource. 303 304void IOHIDDevice::free() 305{ 306 if ( _reportHandlers ) 307 { 308 IOFree( _reportHandlers, 309 sizeof(IOHIDReportHandler) * kReportHandlerSlots ); 310 _reportHandlers = 0; 311 } 312 313 if ( _elementArray ) 314 { 315 _elementArray->release(); 316 _elementArray = 0; 317 } 318 319 if ( _hierarchElements ) 320 { 321 _hierarchElements->release(); 322 _hierarchElements = 0; 323 } 324 325 326 if ( _elementValuesDescriptor ) 327 { 328 _elementValuesDescriptor->release(); 329 _elementValuesDescriptor = 0; 330 } 331 332 if ( _elementLock ) 333 { 334 IORecursiveLockFree( _elementLock ); 335 _elementLock = 0; 336 } 337 338 if ( _clientSet ) 339 { 340 // Should not have any clients. 341 assert(_clientSet->getCount() == 0); 342 _clientSet->release(); 343 _clientSet = 0; 344 } 345 346 if (_inputInterruptElementArray) 347 { 348 _inputInterruptElementArray->release(); 349 _inputInterruptElementArray = 0; 350 } 351 352 if ( _reserved ) 353 { 354 IODelete( _reserved, ExpansionData, 1 ); 355 } 356 357 358 return super::free(); 359} 360 361static inline OSArray * CreateHierarchicalElementList(IOHIDElement * root) 362{ 363 OSArray * resultArray = 0; 364 OSArray * subElements = 0; 365 OSArray * elements = 0; 366 IOHIDElement * element = 0; 367 IOItemCount count; 368 369 if ( !root ) return NULL; 370 371 elements = root->getChildElements(); 372 373 if ( !elements ) return NULL; 374 375 count = elements->getCount(); 376 377 resultArray = OSArray::withCapacity(count); 378 379 if ( !resultArray ) return NULL; 380 381 for ( UInt32 index=0; index < count; index++ ) 382 { 383 element = OSDynamicCast(IOHIDElement, elements->getObject(index)); 384 385 if ( !element ) continue; 386 387 resultArray->setObject(element); 388 389 subElements = CreateHierarchicalElementList(element); 390 391 if ( subElements ) 392 { 393 resultArray->merge(subElements); 394 subElements->release(); 395 subElements = 0; 396 } 397 } 398 399 return resultArray; 400} 401 402 403//--------------------------------------------------------------------------- 404// Start up the IOHIDDevice. 405 406bool IOHIDDevice::start( IOService * provider ) 407{ 408 IOMemoryDescriptor * reportDescriptor; 409 IOReturn ret; 410 411 if ( super::start(provider) != true ) 412 return false; 413 414 // Allocate a mutex lock to serialize report handling. 415 416 _elementLock = IORecursiveLockAlloc(); 417 if ( _elementLock == 0 ) 418 return false; 419 420 // Allocate memory for report handler dispatch table. 421 422 _reportHandlers = (IOHIDReportHandler *) 423 IOMalloc( sizeof(IOHIDReportHandler) * 424 kReportHandlerSlots ); 425 if ( _reportHandlers == 0 ) 426 return false; 427 428 bzero( _reportHandlers, sizeof(IOHIDReportHandler) * kReportHandlerSlots ); 429 430 // Call handleStart() before fetching the report descriptor. 431 432 if ( handleStart(provider) != true ) 433 return false; 434 435 // Fetch report descriptor for the device, and parse it. 436 437 if ( ( newReportDescriptor(&reportDescriptor) != kIOReturnSuccess ) || 438 ( reportDescriptor == 0 ) ) 439 return false; 440 441 IOMemoryMap *tempMap = reportDescriptor->map(); 442 if (tempMap) { 443 OSData *descriptor = OSData::withBytes((void*)tempMap->getVirtualAddress(), tempMap->getSize()); 444 if (descriptor) { 445 setProperty(kIOHIDReportDescriptorKey, descriptor); 446 descriptor->release(); 447 } 448 tempMap->release(); 449 } 450 451 ret = parseReportDescriptor( reportDescriptor ); 452 reportDescriptor->release(); 453 454 if ( ret != kIOReturnSuccess ) 455 return false; 456 457 _hierarchElements = CreateHierarchicalElementList((IOHIDElement *)_elementArray->getObject( 0 )); 458 459 if ( _hierarchElements == NULL ) 460 return false; 461 462 _interfaceNub = IOHIDInterface::withElements( _hierarchElements ); 463 464 if ( _interfaceNub == NULL ) 465 return false; 466 467 // Once the report descriptors have been parsed, we are ready 468 // to handle reports from the device. 469 470 _readyForInputReports = true; 471 472 // Publish properties to the registry before any clients are 473 // attached. 474 475 if ( publishProperties(provider) != true ) 476 return false; 477 478 OSNumber *primaryUsagePage = (OSNumber*)copyProperty(kIOHIDPrimaryUsagePageKey); 479 OSNumber *primaryUsage = (OSNumber*)copyProperty(kIOHIDPrimaryUsageKey); 480 481 // *** GAME DEVICE HACK *** 482 if ((OSDynamicCast(OSNumber, primaryUsagePage) && (primaryUsagePage->unsigned32BitValue() == 0x05)) && 483 (OSDynamicCast(OSNumber, primaryUsage) && (primaryUsage->unsigned32BitValue() == 0x01))) { 484 OSIncrementAtomic(&g3DGameControllerCount); 485 } 486 // *** END GAME DEVICE HACK *** 487 OSSafeReleaseNULL(primaryUsagePage); 488 OSSafeReleaseNULL(primaryUsage); 489 490 if (!gDeviceMatchedNotifier) { 491 OSDictionary * propertyMatch = serviceMatching("IOHIDDevice"); 492 493 gDeviceMatchedNotifier = addMatchingNotification(gIOFirstMatchNotification, 494 propertyMatch, 495 IOHIDDevice::_publishDeviceNotificationHandler, 496 NULL); 497 propertyMatch->release(); 498 } 499 registerService(); 500 501 return true; 502} 503 504//--------------------------------------------------------------------------- 505// Stop the IOHIDDevice. 506bool IOHIDDevice::_publishDeviceNotificationHandler(void * target __unused, 507 void * refCon __unused, 508 IOService * newService, 509 IONotifier * notifier __unused) 510 { 511 IOHIDDevice *self = OSDynamicCast(IOHIDDevice, newService); 512 if (self) { 513 if ( self->_interfaceNub->attach(self) ) 514 { 515 if (!self->_interfaceNub->start(self)) 516 { 517 self->_interfaceNub->detach(self); 518 self->_interfaceNub->release(); 519 self->_interfaceNub = 0; 520 } 521 } 522 else 523 { 524 self->_interfaceNub->release(); 525 self->_interfaceNub = 0; 526 } 527 } 528 return true; 529} 530 531//--------------------------------------------------------------------------- 532// Stop the IOHIDDevice. 533 534void IOHIDDevice::stop(IOService * provider) 535{ 536 // *** GAME DEVICE HACK *** 537 OSNumber *primaryUsagePage = (OSNumber*)copyProperty(kIOHIDPrimaryUsagePageKey); 538 OSNumber *primaryUsage = (OSNumber*)copyProperty(kIOHIDPrimaryUsageKey); 539 540 if ((OSDynamicCast(OSNumber, primaryUsagePage) && (primaryUsagePage->unsigned32BitValue() == 0x05)) && 541 (OSDynamicCast(OSNumber, primaryUsage) && (primaryUsage->unsigned32BitValue() == 0x01))) { 542 OSDecrementAtomic(&g3DGameControllerCount); 543 } 544 OSSafeReleaseNULL(primaryUsagePage); 545 OSSafeReleaseNULL(primaryUsage); 546 // *** END GAME DEVICE HACK *** 547 548 handleStop(provider); 549 550 if ( _elementLock ) 551 { 552 ELEMENT_LOCK; 553 _readyForInputReports = false; 554 ELEMENT_UNLOCK; 555 } 556 557 if (_interfaceNub) 558 { 559 _interfaceNub->release(); 560 _interfaceNub = 0; 561 } 562 563 super::stop(provider); 564} 565 566 567bool IOHIDDevice::matchPropertyTable(OSDictionary * table, SInt32 * score) 568{ 569 bool match = true; 570 RETAIN_ON_STACK(this); 571 572 // Ask our superclass' opinion. 573 if (super::matchPropertyTable(table, score) == false) 574 return false; 575 576 match = MatchPropertyTable(this, table, score); 577 578 // *** HACK *** 579 // RY: For games that are accidentaly matching on the keys 580 // PrimaryUsage = 0x01 581 // PrimaryUsagePage = 0x05 582 // If there no devices present that contain these values, 583 // then return true. 584 if (!match && (g3DGameControllerCount <= 0) && table) { 585 OSNumber *primaryUsage = OSDynamicCast(OSNumber, table->getObject(kIOHIDPrimaryUsageKey)); 586 OSNumber *primaryUsagePage = OSDynamicCast(OSNumber, table->getObject(kIOHIDPrimaryUsagePageKey)); 587 588 if ((primaryUsage && (primaryUsage->unsigned32BitValue() == 0x01)) && 589 (primaryUsagePage && (primaryUsagePage->unsigned32BitValue() == 0x05))) { 590 match = true; 591 IOLog("IOHIDManager: It appears that an application is attempting to locate an invalid device. A workaround is in currently in place, but will be removed after version 10.2\n"); 592 } 593 } 594 // *** END HACK *** 595 596 return match; 597} 598 599 600 601//--------------------------------------------------------------------------- 602// Fetch and publish HID properties to the registry. 603 604bool IOHIDDevice::publishProperties(IOService * provider __unused) 605{ 606#define SET_PROP_FROM_VALUE(key, value) \ 607 do { \ 608 OSObject *prop = value; \ 609 if (prop) { \ 610 setProperty(key, prop); \ 611 _interfaceNub->setProperty(key, prop); \ 612 prop->release(); \ 613 } \ 614 } while (0) 615 616 SET_PROP_FROM_VALUE( kIOHIDTransportKey, newTransportString() ); 617 SET_PROP_FROM_VALUE( kIOHIDVendorIDKey, newVendorIDNumber() ); 618 SET_PROP_FROM_VALUE( kIOHIDVendorIDSourceKey, newVendorIDSourceNumber() ); 619 SET_PROP_FROM_VALUE( kIOHIDProductIDKey, newProductIDNumber() ); 620 SET_PROP_FROM_VALUE( kIOHIDVersionNumberKey, newVersionNumber() ); 621 SET_PROP_FROM_VALUE( kIOHIDManufacturerKey, newManufacturerString() ); 622 SET_PROP_FROM_VALUE( kIOHIDProductKey, newProductString() ); 623 SET_PROP_FROM_VALUE( kIOHIDLocationIDKey, newLocationIDNumber() ); 624 SET_PROP_FROM_VALUE( kIOHIDCountryCodeKey, newCountryCodeNumber() ); 625 SET_PROP_FROM_VALUE( kIOHIDSerialNumberKey, newSerialNumberString() ); 626 SET_PROP_FROM_VALUE( kIOHIDPrimaryUsageKey, newPrimaryUsageNumber() ); 627 SET_PROP_FROM_VALUE( kIOHIDPrimaryUsagePageKey, newPrimaryUsagePageNumber() ); 628 SET_PROP_FROM_VALUE( kIOHIDReportIntervalKey, newReportIntervalNumber() ); 629 SET_PROP_FROM_VALUE( kIOHIDDeviceUsagePairsKey, newDeviceUsagePairs() ); 630 631 if ( getProvider() ) 632 { 633 634 SET_PROP_FROM_VALUE("BootProtocol", getProvider()->copyProperty("bInterfaceProtocol")); 635 SET_PROP_FROM_VALUE("HIDDefaultBehavior", copyProperty("HIDDefaultBehavior")); 636 } 637 638 return true; 639} 640 641//--------------------------------------------------------------------------- 642// Derived from start() and stop(). 643 644bool IOHIDDevice::handleStart(IOService * provider __unused) 645{ 646 return true; 647} 648 649void IOHIDDevice::handleStop(IOService * provider __unused) 650{ 651} 652 653static inline bool ShouldPostDisplayActivityTickles(IOService *device, OSSet * clientSet, bool isSeized) 654{ 655 OSNumber * primaryUsagePage = (OSNumber*)device->copyProperty(kIOHIDPrimaryUsagePageKey); 656 657 if (!clientSet->getCount() || !primaryUsagePage || !OSDynamicCast(OSNumber, primaryUsagePage) || 658 (primaryUsagePage->unsigned32BitValue() != kHIDPage_GenericDesktop)) { 659 OSSafeReleaseNULL(primaryUsagePage); 660 return false; 661 } 662 OSSafeReleaseNULL(primaryUsagePage); 663 664 // We have clients and this device is generic desktop. 665 // Probe the client list to make sure that we are not 666 // openned by an IOHIDEventService. If so, there is 667 // no reason to tickle the display, as the HID System 668 // already does this. 669 OSCollectionIterator * iterator; 670 OSObject * object; 671 bool returnValue = true; 672 673 if ( !isSeized && (iterator = OSCollectionIterator::withCollection(clientSet)) ) 674 { 675 bool done = false; 676 while (!done) { 677 iterator->reset(); 678 while (!done && (NULL != (object = iterator->getNextObject()))) { 679 if ( object->metaCast("IOHIDEventService")) 680 { 681 returnValue = false; 682 done = true; 683 } 684 } 685 if (iterator->isValid()) { 686 done = true; 687 } 688 } 689 iterator->release(); 690 } 691 return returnValue; 692} 693 694static inline bool ShouldPostDisplayActivityTicklesForWakeDevice( 695 IOService *device, OSSet * clientSet, bool isSeized) 696{ 697 OSNumber * primaryUsagePage = OSDynamicCast(OSNumber, device->copyProperty(kIOHIDPrimaryUsagePageKey)); 698 if (!primaryUsagePage) 699 return false; 700 701 if (primaryUsagePage->unsigned32BitValue() == kHIDPage_Consumer) 702 return true; 703 704 if (!clientSet->getCount() || 705 (primaryUsagePage->unsigned32BitValue() != kHIDPage_GenericDesktop)) 706 return false; 707 OSSafeReleaseNULL(primaryUsagePage); 708 709 // We have clients and this device is generic desktop. 710 // Probe the client list to make sure that we are 711 // openned by an IOHIDEventService. 712 713 OSCollectionIterator * iterator; 714 OSObject * object; 715 bool returnValue = false; 716 717 if ( !isSeized && (iterator = OSCollectionIterator::withCollection(clientSet)) ) 718 { 719 bool done = false; 720 while (!done) { 721 iterator->reset(); 722 while (!done && (NULL != (object = iterator->getNextObject()))) { 723 if (object->metaCast("IOHIDEventService")) 724 { 725 returnValue = true; 726 done = true; 727 } 728 } 729 if (iterator->isValid()) { 730 done = true; 731 } 732 } 733 iterator->release(); 734 } 735 return returnValue; 736} 737 738//--------------------------------------------------------------------------- 739// Handle a client open on the interface. 740 741bool IOHIDDevice::handleOpen(IOService *client, 742 IOOptionBits options, 743 void *argument __unused) 744{ 745 bool accept = false; 746 747 do { 748 if ( _seizedClient ) 749 break; 750 751 // Was this object already registered as our client? 752 753 if ( _clientSet->containsObject(client) ) 754 { 755 DLOG("%s: multiple opens from client %lx\n", 756 getName(), (UInt32) client); 757 accept = true; 758 break; 759 } 760 761 // Add the new client object to our client set. 762 763 if ( _clientSet->setObject(client) == false ) 764 break; 765 766 if (options & kIOServiceSeize) 767 { 768 messageClients( kIOMessageServiceIsRequestingClose, (void*)(intptr_t)options); 769 770 _seizedClient = client; 771 772#if !TARGET_OS_EMBEDDED 773 IOHIKeyboard * keyboard = OSDynamicCast(IOHIKeyboard, getProvider()); 774 IOHIPointing * pointing = OSDynamicCast(IOHIPointing, getProvider()); 775 if ( keyboard ) 776 keyboard->IOHIKeyboard::message(kIOHIDSystemDeviceSeizeRequestMessage, this, (void *)true); 777 else if ( pointing ) 778 pointing->IOHIPointing::message(kIOHIDSystemDeviceSeizeRequestMessage, this, (void *)true); 779#endif 780 } 781 782 accept = true; 783 } 784 while (false); 785 786 _performTickle = ShouldPostDisplayActivityTickles(this, _clientSet, _seizedClient); 787 _performWakeTickle = ShouldPostDisplayActivityTicklesForWakeDevice(this, _clientSet, _seizedClient); 788 789 return accept; 790} 791 792//--------------------------------------------------------------------------- 793// Handle a client close on the interface. 794 795void IOHIDDevice::handleClose(IOService * client, IOOptionBits options __unused) 796{ 797 // Remove the object from the client OSSet. 798 799 if ( _clientSet->containsObject(client) ) 800 { 801 // Remove the client from our OSSet. 802 _clientSet->removeObject(client); 803 804 if (client == _seizedClient) 805 { 806 _seizedClient = 0; 807 808#if !TARGET_OS_EMBEDDED 809 IOHIKeyboard * keyboard = OSDynamicCast(IOHIKeyboard, getProvider()); 810 IOHIPointing * pointing = OSDynamicCast(IOHIPointing, getProvider()); 811 if ( keyboard ) 812 keyboard->IOHIKeyboard::message(kIOHIDSystemDeviceSeizeRequestMessage, this, (void *)false); 813 else if ( pointing ) 814 pointing->IOHIPointing::message(kIOHIDSystemDeviceSeizeRequestMessage, this, (void *)false); 815#endif 816 } 817 818 _performTickle = ShouldPostDisplayActivityTickles(this, _clientSet, _seizedClient); 819 _performWakeTickle = ShouldPostDisplayActivityTicklesForWakeDevice(this, _clientSet, _seizedClient); 820 } 821} 822 823//--------------------------------------------------------------------------- 824// Query whether a client has an open on the interface. 825 826bool IOHIDDevice::handleIsOpen(const IOService * client) const 827{ 828 if (client) 829 return _clientSet->containsObject(client); 830 else 831 return (_clientSet->getCount() > 0); 832} 833 834 835//--------------------------------------------------------------------------- 836// Create a new user client. 837 838IOReturn IOHIDDevice::newUserClient( task_t owningTask, 839 void * security_id, 840 UInt32 type, 841 OSDictionary * properties, 842 IOUserClient ** handler ) 843{ 844 // RY: This is really skanky. Apparently there are some subclasses out there 845 // that want all the benefits of IOHIDDevice w/o supporting the default HID 846 // User Client. I know! Shocking! Anyway, passing a type known only to the 847 // default hid clients to ensure that at least connect to our correct client. 848 if ( type == kIOHIDLibUserClientConnectManager ) { 849 if ( isInactive() ) { 850 IOLog( "IOHIDDevice::newUserClient called on an inactive device\n" ); 851 *handler = NULL; 852 return kIOReturnNotReady; 853 } 854 855 if ( properties ) { 856 properties->setObject( kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue ); 857 } 858 859 IOWorkLoop *loop = getWorkLoop(); 860 861 IOReturn result = kIOReturnNotReady; 862 863 if ( loop ) { 864 result = loop->runAction( OSMemberFunctionCast( IOWorkLoop::Action, this, &IOHIDDevice::newUserClientGated ), 865 this, owningTask, security_id, properties, handler ); 866 } 867 else { 868 IOLog( "IOHIDDevice::newUserClient failed to get a workloop\n" ); 869 } 870 871 return result; 872 } 873 874 return super::newUserClient( owningTask, security_id, type, properties, handler ); 875} 876 877IOReturn IOHIDDevice::newUserClientGated( task_t owningTask, 878 void * security_id, 879 OSDictionary * properties, 880 IOUserClient ** handler ) 881{ 882 IOUserClient * client = new IOHIDLibUserClient; 883 884 if ( !client->initWithTask( owningTask, security_id, kIOHIDLibUserClientConnectManager, properties ) ) { 885 client->release(); 886 return kIOReturnBadArgument; 887 } 888 889 if ( !client->attach( this ) ) { 890 client->release(); 891 return kIOReturnUnsupported; 892 } 893 894 if ( !client->start( this ) ) { 895 client->detach( this ); 896 client->release(); 897 return kIOReturnUnsupported; 898 } 899 900 *handler = client; 901 902 return kIOReturnSuccess; 903} 904 905//--------------------------------------------------------------------------- 906// Handle provider messages. 907 908IOReturn IOHIDDevice::message( UInt32 type, IOService * provider, void * argument ) 909{ 910 if ((kIOMessageDeviceSignaledWakeup == type) && _performWakeTickle) 911 { 912 IOHIDSystemActivityTickle(NX_HARDWARE_TICKLE, this); // not a real event. tickle is not maskable. 913 return kIOReturnSuccess; 914 } 915 916 return super::message(type, provider, argument); 917} 918 919//--------------------------------------------------------------------------- 920// Default implementation of the HID property 'getter' functions. 921 922OSString * IOHIDDevice::newTransportString() const 923{ 924 return 0; 925} 926 927OSString * IOHIDDevice::newManufacturerString() const 928{ 929 return 0; 930} 931 932OSString * IOHIDDevice::newProductString() const 933{ 934 return 0; 935} 936 937OSNumber * IOHIDDevice::newVendorIDNumber() const 938{ 939 return 0; 940} 941 942OSNumber * IOHIDDevice::newProductIDNumber() const 943{ 944 return 0; 945} 946 947OSNumber * IOHIDDevice::newVersionNumber() const 948{ 949 return 0; 950} 951 952OSNumber * IOHIDDevice::newSerialNumber() const 953{ 954 return 0; 955} 956 957OSNumber * IOHIDDevice::newPrimaryUsageNumber() const 958{ 959 OSArray * childArray; 960 IOHIDElementPrivate * child; 961 IOHIDElementPrivate * root; 962 963 if ( (root = (IOHIDElementPrivate *) _elementArray->getObject(0)) && 964 (childArray = root->getChildElements()) && 965 (child = (IOHIDElementPrivate *) childArray->getObject(0)) ) 966 { 967 return OSNumber::withNumber(child->getUsage(), 32); 968 } 969 970 return 0; 971} 972 973OSNumber * IOHIDDevice::newPrimaryUsagePageNumber() const 974{ 975 OSArray * childArray; 976 IOHIDElementPrivate * child; 977 IOHIDElementPrivate * root; 978 979 if ( (root = (IOHIDElementPrivate *) _elementArray->getObject(0)) && 980 (childArray = root->getChildElements()) && 981 (child = (IOHIDElementPrivate *) childArray->getObject(0)) ) 982 { 983 return OSNumber::withNumber(child->getUsagePage(), 32); 984 } 985 986 return 0; 987} 988 989//--------------------------------------------------------------------------- 990// Handle input reports (USB Interrupt In pipe) from the device. 991 992IOReturn IOHIDDevice::handleReport( IOMemoryDescriptor * report, 993 IOHIDReportType reportType, 994 IOOptionBits options ) 995{ 996 AbsoluteTime currentTime; 997 998 clock_get_uptime( ¤tTime ); 999 1000 return handleReportWithTime( currentTime, report, reportType, options ); 1001} 1002 1003//--------------------------------------------------------------------------- 1004// Get a report from the device. 1005 1006IOReturn IOHIDDevice::getReport( IOMemoryDescriptor * report, 1007 IOHIDReportType reportType, 1008 IOOptionBits options ) 1009{ 1010 return getReport(report, reportType, options, 0, 0); 1011} 1012 1013//--------------------------------------------------------------------------- 1014// Send a report to the device. 1015 1016IOReturn IOHIDDevice::setReport( IOMemoryDescriptor * report, 1017 IOHIDReportType reportType, 1018 IOOptionBits options) 1019{ 1020 return setReport(report, reportType, options, 0, 0); 1021} 1022 1023//--------------------------------------------------------------------------- 1024// Parse a report descriptor, and update the property table with 1025// the IOHIDElementPrivate hierarchy discovered. 1026 1027IOReturn IOHIDDevice::parseReportDescriptor( IOMemoryDescriptor * report, 1028 IOOptionBits options __unused) 1029{ 1030 OSStatus status = kIOReturnError; 1031 HIDPreparsedDataRef parseData; 1032 void * reportData; 1033 IOByteCount reportLength; 1034 IOReturn ret; 1035 1036 reportLength = report->getLength(); 1037 1038 if ( !reportLength ) 1039 return kIOReturnBadArgument; 1040 1041 reportData = IOMalloc(reportLength); 1042 1043 if ( !reportData ) 1044 return kIOReturnNoMemory; 1045 1046 report->readBytes( 0, reportData, reportLength ); 1047 1048 // Parse the report descriptor. 1049 1050 status = HIDOpenReportDescriptor( 1051 reportData, /* report descriptor */ 1052 reportLength, /* report size in bytes */ 1053 &parseData, /* pre-parse data */ 1054 0 ); /* flags */ 1055 1056 // Release the buffer 1057 IOFree( reportData, reportLength ); 1058 1059 if ( status != kHIDSuccess ) 1060 { 1061 return kIOReturnError; 1062 } 1063 1064 // Create a hierarchy of IOHIDElementPrivate objects. 1065 1066 ret = createElementHierarchy( parseData ); 1067 1068 getReportCountAndSizes( parseData ); 1069 1070 // Release memory. 1071 1072 HIDCloseReportDescriptor( parseData ); 1073 1074 return ret; 1075} 1076 1077//--------------------------------------------------------------------------- 1078// Build the element hierarchy to describe the device capabilities to 1079// user-space. 1080 1081IOReturn 1082IOHIDDevice::createElementHierarchy( HIDPreparsedDataRef parseData ) 1083{ 1084 OSStatus status; 1085 HIDCapabilities caps; 1086 IOReturn ret = kIOReturnNoMemory; 1087 1088 do { 1089 // Get a summary of device capabilities. 1090 1091 status = HIDGetCapabilities( parseData, &caps ); 1092 if ( status != kHIDSuccess ) 1093 { 1094 ret = kIOReturnError; 1095 break; 1096 } 1097 1098 // Dump HIDCapabilities structure contents. 1099 1100 DLOG("Report bytes: input:%ld output:%ld feature:%ld\n", 1101 caps.inputReportByteLength, 1102 caps.outputReportByteLength, 1103 caps.featureReportByteLength); 1104 DLOG("Collections : %ld\n", caps.numberCollectionNodes); 1105 DLOG("Buttons : input:%ld output:%ld feature:%ld\n", 1106 caps.numberInputButtonCaps, 1107 caps.numberOutputButtonCaps, 1108 caps.numberFeatureButtonCaps); 1109 DLOG("Values : input:%ld output:%ld feature:%ld\n", 1110 caps.numberInputValueCaps, 1111 caps.numberOutputValueCaps, 1112 caps.numberFeatureValueCaps); 1113 1114 _maxInputReportSize = caps.inputReportByteLength; 1115 _maxOutputReportSize = caps.outputReportByteLength; 1116 _maxFeatureReportSize = caps.featureReportByteLength; 1117 1118 // RY: These values are useful to the subclasses. Post them. 1119 setProperty(kIOHIDMaxInputReportSizeKey, _maxInputReportSize, 32); 1120 setProperty(kIOHIDMaxOutputReportSizeKey, _maxOutputReportSize, 32); 1121 setProperty(kIOHIDMaxFeatureReportSizeKey, _maxFeatureReportSize, 32); 1122 1123 1124 // Create an OSArray to store all HID elements. 1125 1126 _elementArray = OSArray::withCapacity( 1127 caps.numberCollectionNodes + 1128 caps.numberInputButtonCaps + 1129 caps.numberInputValueCaps + 1130 caps.numberOutputButtonCaps + 1131 caps.numberOutputValueCaps + 1132 caps.numberFeatureButtonCaps + 1133 caps.numberFeatureValueCaps + 1134 10 ); 1135 if ( _elementArray == 0 ) break; 1136 1137 _elementArray->setCapacityIncrement(10); 1138 1139 // Add collections to the element array. 1140 1141 if ( !createCollectionElements( 1142 parseData, 1143 _elementArray, 1144 caps.numberCollectionNodes ) ) break; 1145 1146 // Everything added to the element array from this point on 1147 // are "data" elements. We cache the starting index. 1148 1149 _dataElementIndex = _elementArray->getCount(); 1150 1151 // Add input buttons to the element array. 1152 1153 if ( !createButtonElements( parseData, 1154 _elementArray, 1155 kHIDInputReport, 1156 kIOHIDElementTypeInput_Button, 1157 caps.numberInputButtonCaps ) ) break; 1158 1159 // Add output buttons to the element array. 1160 1161 if ( !createButtonElements( parseData, 1162 _elementArray, 1163 kHIDOutputReport, 1164 kIOHIDElementTypeOutput, 1165 caps.numberOutputButtonCaps ) ) break; 1166 1167 // Add feature buttons to the element array. 1168 1169 if ( !createButtonElements( parseData, 1170 _elementArray, 1171 kHIDFeatureReport, 1172 kIOHIDElementTypeFeature, 1173 caps.numberFeatureButtonCaps ) ) break; 1174 1175 // Add input values to the element array. 1176 1177 if ( !createValueElements( parseData, 1178 _elementArray, 1179 kHIDInputReport, 1180 kIOHIDElementTypeInput_Misc, 1181 caps.numberInputValueCaps ) ) break; 1182 1183 // Add output values to the element array. 1184 1185 if ( !createValueElements( parseData, 1186 _elementArray, 1187 kHIDOutputReport, 1188 kIOHIDElementTypeOutput, 1189 caps.numberOutputValueCaps ) ) break; 1190 1191 // Add feature values to the element array. 1192 1193 if ( !createValueElements( parseData, 1194 _elementArray, 1195 kHIDFeatureReport, 1196 kIOHIDElementTypeFeature, 1197 caps.numberFeatureValueCaps ) ) break; 1198 1199 // Add the input report handler to the element array. 1200 if ( !createReportHandlerElements(parseData) ) break; 1201 1202 1203 // Create a memory to store current element values. 1204 1205 _elementValuesDescriptor = createMemoryForElementValues(); 1206 if ( _elementValuesDescriptor == 0 ) 1207 break; 1208 1209 // Element hierarchy has been built, add it to the property table. 1210 1211 IOHIDElementPrivate * root = (IOHIDElementPrivate *) _elementArray->getObject( 0 ); 1212 if ( root ) 1213 { 1214 setProperty( kIOHIDElementKey, root->getChildElements() ); 1215 } 1216 1217 // Add the interrupt report handlers to the property table as well. 1218 setProperty(kIOHIDInputReportElementsKey, 1219 _inputInterruptElementArray); 1220 1221 ret = kIOReturnSuccess; 1222 } 1223 while ( false ); 1224 1225 return ret; 1226} 1227 1228//--------------------------------------------------------------------------- 1229// Fetch the all the possible functions of the device 1230 1231static OSDictionary * CreateDeviceUsagePairFromElement(IOHIDElementPrivate * element) 1232{ 1233 OSDictionary * pair = 0; 1234 OSNumber * usage = 0; 1235 OSNumber * usagePage = 0; 1236 OSNumber * type = 0; 1237 1238 pair = OSDictionary::withCapacity(2); 1239 usage = OSNumber::withNumber(element->getUsage(), 32); 1240 usagePage = OSNumber::withNumber(element->getUsagePage(), 32); 1241 type = OSNumber::withNumber(element->getCollectionType(), 32); 1242 1243 pair->setObject(kIOHIDDeviceUsageKey, usage); 1244 pair->setObject(kIOHIDDeviceUsagePageKey, usagePage); 1245 //pair->setObject(kIOHIDElementCollectionTypeKey, type); 1246 1247 usage->release(); 1248 usagePage->release(); 1249 type->release(); 1250 1251 return pair; 1252 } 1253 1254OSArray * IOHIDDevice::newDeviceUsagePairs() 1255{ 1256 IOHIDElementPrivate * element = 0; 1257 OSArray * functions = 0; 1258 OSDictionary * pair = 0; 1259 UInt32 elementCount = _elementArray->getCount(); 1260 1261 if ( elementCount <= 1 ) // this include vitual collection 1262 return NULL; 1263 1264 functions = OSArray::withCapacity(2); 1265 1266 // starts at one to avoid the virtual collection 1267 for (unsigned i=1; i<elementCount; i++) 1268 { 1269 element = (IOHIDElementPrivate *)_elementArray->getObject(i); 1270 1271 if ((element->getType() == kIOHIDElementTypeCollection) && 1272 ((element->getCollectionType() == kIOHIDElementCollectionTypeApplication) || 1273 (element->getCollectionType() == kIOHIDElementCollectionTypePhysical))) 1274 { 1275 pair = CreateDeviceUsagePairFromElement(element); 1276 1277 UInt32 pairCount = functions->getCount(); 1278 bool found = false; 1279 for(unsigned j=0; j<pairCount; j++) 1280 { 1281 OSDictionary *tempPair = (OSDictionary *)functions->getObject(j); 1282 found = tempPair->isEqualTo(pair); 1283 if (found) 1284 break; 1285 } 1286 1287 if (!found) 1288 { 1289 functions->setObject(functions->getCount(), pair); 1290 } 1291 1292 pair->release(); 1293 } 1294 } 1295 1296 if ( ! functions->getCount() ) { 1297 pair = CreateDeviceUsagePairFromElement((IOHIDElementPrivate *)_elementArray->getObject(1)); 1298 functions->setObject(pair); 1299 pair->release(); 1300 } 1301 1302 return functions; 1303} 1304 1305 1306//--------------------------------------------------------------------------- 1307// Fetch the total number of reports and the size of each report. 1308 1309bool IOHIDDevice::getReportCountAndSizes( HIDPreparsedDataRef parseData ) 1310{ 1311 HIDPreparsedDataPtr data = (HIDPreparsedDataPtr) parseData; 1312 HIDReportSizes * report = data->reports; 1313 1314 _reportCount = data->reportCount; 1315 1316 DLOG("Report count: %ld\n", _reportCount); 1317 1318 for ( UInt32 num = 0; num < data->reportCount; num++, report++ ) 1319 { 1320 1321 DLOG("Report ID: %ld input:%ld output:%ld feature:%ld\n", 1322 report->reportID, 1323 report->inputBitCount, 1324 report->outputBitCount, 1325 report->featureBitCount); 1326 1327 setReportSize( report->reportID, 1328 kIOHIDReportTypeInput, 1329 report->inputBitCount ); 1330 1331 setReportSize( report->reportID, 1332 kIOHIDReportTypeOutput, 1333 report->outputBitCount ); 1334 1335 setReportSize( report->reportID, 1336 kIOHIDReportTypeFeature, 1337 report->featureBitCount ); 1338 } 1339 1340 return true; 1341} 1342 1343//--------------------------------------------------------------------------- 1344// Set the report size for the first element in the report handler chain. 1345 1346bool IOHIDDevice::setReportSize( UInt8 reportID, 1347 IOHIDReportType reportType, 1348 UInt32 numberOfBits ) 1349{ 1350 IOHIDElementPrivate * element; 1351 bool ret = false; 1352 1353 element = GetHeadElement( GetReportHandlerSlot(reportID), reportType ); 1354 1355 while ( element ) 1356 { 1357 if ( element->getReportID() == reportID ) 1358 { 1359 element->setReportSize( numberOfBits ); 1360 ret = true; 1361 break; 1362 } 1363 element = element->getNextReportHandler(); 1364 } 1365 return ret; 1366} 1367 1368//--------------------------------------------------------------------------- 1369// Add collection elements to the OSArray object provided. 1370 1371bool 1372IOHIDDevice::createCollectionElements( HIDPreparsedDataRef parseData, 1373 OSArray * array, 1374 UInt32 maxCount ) 1375{ 1376 OSStatus status; 1377 HIDCollectionExtendedNodePtr collections; 1378 UInt32 count = maxCount; 1379 bool ret = false; 1380 UInt32 index; 1381 1382 do { 1383 // Allocate memory to fetch all collections from the parseData. 1384 1385 collections = (HIDCollectionExtendedNodePtr) 1386 IOMalloc( maxCount * sizeof(HIDCollectionExtendedNode) ); 1387 1388 if ( collections == 0 ) break; 1389 1390 status = HIDGetCollectionExtendedNodes( 1391 collections, /* collectionNodes */ 1392 &count, /* collectionNodesSize */ 1393 parseData ); /* preparsedDataRef */ 1394 1395 if ( status != kHIDSuccess ) break; 1396 1397 // Create an IOHIDElementPrivate for each collection. 1398 1399 for ( index = 0; index < count; index++ ) 1400 { 1401 IOHIDElementPrivate * element; 1402 1403 element = IOHIDElementPrivate::collectionElement( 1404 this, 1405 kIOHIDElementTypeCollection, 1406 &collections[index] ); 1407 if ( element == 0 ) break; 1408 1409 element->release(); 1410 } 1411 if ( index < count ) break; 1412 1413 // Create linkage for the collection hierarchy. 1414 // Starts at 1 to skip the root (virtual) collection. 1415 1416 for ( index = 1; index < count; index++ ) 1417 { 1418 if ( !linkToParent( array, collections[index].parent, index ) ) 1419 break; 1420 } 1421 if ( index < count ) break; 1422 1423 ret = true; 1424 } 1425 while ( false ); 1426 1427 if ( collections ) 1428 IOFree( collections, maxCount * sizeof(HIDCollectionExtendedNode) ); 1429 1430 return ret; 1431} 1432 1433//--------------------------------------------------------------------------- 1434// Link an element in the array to another element in the array as its child. 1435 1436bool IOHIDDevice::linkToParent( const OSArray * array, 1437 UInt32 parentIndex, 1438 UInt32 childIndex ) 1439{ 1440 IOHIDElementPrivate * child = (IOHIDElementPrivate *) array->getObject( childIndex ); 1441 IOHIDElementPrivate * parent = (IOHIDElementPrivate *) array->getObject( parentIndex ); 1442 1443 return ( parent ) ? parent->addChildElement( child ) : false; 1444} 1445 1446//--------------------------------------------------------------------------- 1447// Add Button elements (1 bit value) to the collection. 1448 1449bool IOHIDDevice::createButtonElements( HIDPreparsedDataRef parseData, 1450 OSArray * array, 1451 UInt32 hidReportType, 1452 IOHIDElementType elementType, 1453 UInt32 maxCount ) 1454{ 1455 OSStatus status; 1456 HIDButtonCapabilitiesPtr buttons = 0; 1457 UInt32 count = maxCount; 1458 bool ret = false; 1459 IOHIDElementPrivate * element; 1460 IOHIDElementPrivate * parent; 1461 1462 do { 1463 if ( maxCount == 0 ) 1464 { 1465 ret = true; 1466 break; 1467 } 1468 1469 // Allocate memory to fetch all button elements from the parseData. 1470 1471 buttons = (HIDButtonCapabilitiesPtr) IOMalloc( maxCount * 1472 sizeof(HIDButtonCapabilities) ); 1473 if ( buttons == 0 ) break; 1474 1475 status = HIDGetButtonCapabilities( hidReportType, /* HIDReportType */ 1476 buttons, /* buttonCaps */ 1477 &count, /* buttonCapsSize */ 1478 parseData ); /* preparsedDataRef */ 1479 1480 if ( status != kHIDSuccess ) break; 1481 1482 // Create an IOHIDElementPrivate for each button and link it to its 1483 // parent collection. 1484 1485 ret = true; 1486 1487 for ( UInt32 i = 0; i < count; i++ ) 1488 { 1489 parent = (IOHIDElementPrivate *) array->getObject( 1490 buttons[i].collection ); 1491 1492 element = IOHIDElementPrivate::buttonElement( 1493 this, 1494 elementType, 1495 &buttons[i], 1496 parent ); 1497 if ( element == 0 ) 1498 { 1499 ret = false; 1500 break; 1501 } 1502 element->release(); 1503 } 1504 } 1505 while ( false ); 1506 1507 if ( buttons ) 1508 IOFree( buttons, maxCount * sizeof(HIDButtonCapabilities) ); 1509 1510 return ret; 1511} 1512 1513//--------------------------------------------------------------------------- 1514// Add Value elements to the collection. 1515 1516bool IOHIDDevice::createValueElements( HIDPreparsedDataRef parseData, 1517 OSArray * array, 1518 UInt32 hidReportType, 1519 IOHIDElementType elementType, 1520 UInt32 maxCount ) 1521{ 1522 OSStatus status; 1523 HIDValueCapabilitiesPtr values = 0; 1524 UInt32 count = maxCount; 1525 bool ret = false; 1526 IOHIDElementPrivate * element; 1527 IOHIDElementPrivate * parent; 1528 1529 do { 1530 if ( maxCount == 0 ) 1531 { 1532 ret = true; 1533 break; 1534 } 1535 1536 // Allocate memory to fetch all value elements from the parseData. 1537 1538 values = (HIDValueCapabilitiesPtr) IOMalloc( maxCount * 1539 sizeof(HIDValueCapabilities) ); 1540 if ( values == 0 ) break; 1541 1542 status = HIDGetValueCapabilities( hidReportType, /* HIDReportType */ 1543 values, /* valueCaps */ 1544 &count, /* valueCapsSize */ 1545 parseData ); /* preparsedDataRef */ 1546 1547 if ( status != kHIDSuccess ) break; 1548 1549 // Create an IOHIDElementPrivate for each value and link it to its 1550 // parent collection. 1551 1552 ret = true; 1553 1554 for ( UInt32 i = 0; i < count; i++ ) 1555 { 1556 parent = (IOHIDElementPrivate *) array->getObject( 1557 values[i].collection ); 1558 1559 element = IOHIDElementPrivate::valueElement( 1560 this, 1561 elementType, 1562 &values[i], 1563 parent ); 1564 1565 if ( element == 0 ) 1566 { 1567 ret = false; 1568 break; 1569 } 1570 element->release(); 1571 } 1572 } 1573 while ( false ); 1574 1575 if ( values ) 1576 IOFree( values, maxCount * sizeof(HIDValueCapabilities) ); 1577 1578 return ret; 1579} 1580 1581//--------------------------------------------------------------------------- 1582// Add report handler elements. 1583 1584bool IOHIDDevice::createReportHandlerElements( HIDPreparsedDataRef parseData) 1585{ 1586 HIDPreparsedDataPtr data = (HIDPreparsedDataPtr) parseData; 1587 HIDReportSizes * report = data->reports; 1588 IOHIDElementPrivate * element = 0; 1589 1590 if ( !(_inputInterruptElementArray = OSArray::withCapacity(data->reportCount))) 1591 return false; 1592 1593 for ( UInt32 num = 0; num < data->reportCount; num++, report++ ) 1594 { 1595 element = IOHIDElementPrivate::reportHandlerElement( 1596 this, 1597 kIOHIDElementTypeInput_Misc, 1598 report->reportID, 1599 report->inputBitCount); 1600 1601 if ( element == 0 ) 1602 continue; 1603 1604 _inputInterruptElementArray->setObject(element); 1605 1606 element->release(); 1607 } 1608 1609 return true; 1610} 1611 1612//--------------------------------------------------------------------------- 1613// Called by an IOHIDElementPrivate to register itself. 1614 1615bool IOHIDDevice::registerElement( IOHIDElementPrivate * element, 1616 IOHIDElementCookie * cookie ) 1617{ 1618 IOHIDReportType reportType; 1619 UInt32 index = _elementArray->getCount(); 1620 1621 // Add the element to the elements array. 1622 1623 if ( _elementArray->setObject( index, element ) != true ) 1624 { 1625 return false; 1626 } 1627 1628 // If the element can contribute to an Input, Output, or Feature 1629 // report, then add it to the chain of report handlers. 1630 if ( element->getReportType( &reportType ) ) 1631 { 1632 IOHIDReportHandler * reportHandler; 1633 UInt32 slot; 1634 1635 slot = GetReportHandlerSlot( element->getReportID() ); 1636 1637 reportHandler = &_reportHandlers[slot]; 1638 1639 if ( reportHandler->head[reportType] ) 1640 { 1641 element->setNextReportHandler( reportHandler->head[reportType] ); 1642 } 1643 reportHandler->head[reportType] = element; 1644 1645 if ( element->getUsagePage() == kHIDPage_KeyboardOrKeypad ) 1646 { 1647 UInt32 usage = element->getUsage(); 1648 1649 if ( usage == kHIDUsage_KeyboardErrorRollOver) 1650 _rollOverElement = element; 1651 1652 if ( usage >= kHIDUsage_KeyboardLeftControl && usage <= kHIDUsage_KeyboardRightGUI ) 1653 element->setRollOverElementPtr(&(_rollOverElement)); 1654 } 1655 } 1656 1657 // The cookie returned is simply an index to the element in the 1658 // elements array. We may decide to obfuscate it later on. 1659 1660 *cookie = (IOHIDElementCookie) index; 1661 1662 return true; 1663} 1664 1665//--------------------------------------------------------------------------- 1666// Create a buffer memory descriptor, and divide the memory buffer 1667// for each data element. 1668IOBufferMemoryDescriptor * IOHIDDevice::createMemoryForElementValues() 1669{ 1670 IOBufferMemoryDescriptor * descriptor; 1671 IOHIDElementPrivate * element; 1672 UInt32 capacity = 0; 1673 UInt8 * beginning; 1674 UInt8 * buffer; 1675 1676 // Discover the amount of memory required to publish the 1677 // element values for all "data" elements. 1678 1679 for ( UInt32 slot = 0; slot < kReportHandlerSlots; slot++ ) { 1680 for ( UInt32 type = 0; type < kIOHIDReportTypeCount; type++ ) { 1681 element = GetHeadElement(slot, type); 1682 while ( element ) { 1683 UInt32 remaining = ULONG_MAX - capacity; 1684 1685 if ( element->getElementValueSize() > remaining ) 1686 return NULL; 1687 1688 capacity += element->getElementValueSize(); 1689 element = element->getNextReportHandler(); 1690 } 1691 } 1692 } 1693 1694 // Allocate an IOBufferMemoryDescriptor object. 1695 1696 DLOG("Element value capacity %ld\n", capacity); 1697 1698 descriptor = IOBufferMemoryDescriptor::withOptions( 1699 kIOMemoryKernelUserShared, 1700 capacity ); 1701 1702 if ( ( descriptor == 0 ) || ( descriptor->getBytesNoCopy() == 0 ) ) { 1703 if ( descriptor ) descriptor->release(); 1704 return 0; 1705 } 1706 1707 // Now assign the update memory area for each report element. 1708 beginning = buffer = (UInt8 *) descriptor->getBytesNoCopy(); 1709 1710 for ( UInt32 slot = 0; slot < kReportHandlerSlots; slot++ ) { 1711 for ( UInt32 type = 0; type < kIOHIDReportTypeCount; type++ ) { 1712 element = GetHeadElement(slot, type); 1713 while ( element ) { 1714 assert ( buffer < (beginning + capacity) ); 1715 1716 if(buffer >= (beginning + capacity)) { 1717 descriptor->release(); 1718 return 0; 1719 } 1720 1721 element->setMemoryForElementValue( (IOVirtualAddress) buffer, 1722 (void *) (buffer - beginning)); 1723 1724 buffer += element->getElementValueSize(); 1725 element = element->getNextReportHandler(); 1726 } 1727 } 1728 } 1729 1730 return descriptor; 1731} 1732 1733//--------------------------------------------------------------------------- 1734// Get a reference to the memory descriptor created by 1735// createMemoryForElementValues(). 1736 1737IOMemoryDescriptor * IOHIDDevice::getMemoryWithCurrentElementValues() const 1738{ 1739 return _elementValuesDescriptor; 1740} 1741 1742//--------------------------------------------------------------------------- 1743// Start delivering events from the given element to the specified 1744// event queue. 1745 1746IOReturn IOHIDDevice::startEventDelivery( IOHIDEventQueue * queue, 1747 IOHIDElementCookie cookie, 1748 IOOptionBits options __unused) 1749{ 1750 IOHIDElementPrivate * element; 1751 UInt32 elementIndex = (UInt32) cookie; 1752 IOReturn ret = kIOReturnBadArgument; 1753 1754 if ( ( queue == 0 ) || ( elementIndex < _dataElementIndex ) ) 1755 return kIOReturnBadArgument; 1756 1757 ELEMENT_LOCK; 1758 1759 do { 1760 if (( element = GetElement(elementIndex) ) == 0) 1761 break; 1762 1763 ret = element->addEventQueue( queue ) ? 1764 kIOReturnSuccess : kIOReturnNoMemory; 1765 } 1766 while ( false ); 1767 1768 ELEMENT_UNLOCK; 1769 1770 return ret; 1771} 1772 1773//--------------------------------------------------------------------------- 1774// Stop delivering events from the given element to the specified 1775// event queue. 1776 1777IOReturn IOHIDDevice::stopEventDelivery( IOHIDEventQueue * queue, 1778 IOHIDElementCookie cookie ) 1779{ 1780 IOHIDElementPrivate * element; 1781 UInt32 elementIndex = (UInt32) cookie; 1782 bool removed = false; 1783 1784 // If the cookie provided was zero, then loop and remove the queue 1785 // from all elements. 1786 1787 if ( elementIndex == 0 ) 1788 elementIndex = _dataElementIndex; 1789 else if ( (queue == 0 ) || ( elementIndex < _dataElementIndex ) ) 1790 return kIOReturnBadArgument; 1791 1792 ELEMENT_LOCK; 1793 1794 do { 1795 if (( element = GetElement(elementIndex++) ) == 0) 1796 break; 1797 1798 removed = element->removeEventQueue( queue ) || removed; 1799 } 1800 while ( cookie == 0 ); 1801 1802 ELEMENT_UNLOCK; 1803 1804 return removed ? kIOReturnSuccess : kIOReturnNotFound; 1805} 1806 1807//--------------------------------------------------------------------------- 1808// Check whether events from the given element will be delivered to 1809// the specified event queue. 1810 1811IOReturn IOHIDDevice::checkEventDelivery( IOHIDEventQueue * queue, 1812 IOHIDElementCookie cookie, 1813 bool * started ) 1814{ 1815 IOHIDElementPrivate * element = GetElement( cookie ); 1816 1817 if ( !queue || !element || !started ) 1818 return kIOReturnBadArgument; 1819 1820 ELEMENT_LOCK; 1821 1822 *started = element->hasEventQueue( queue ); 1823 1824 ELEMENT_UNLOCK; 1825 1826 return kIOReturnSuccess; 1827} 1828 1829#define SetCookiesTransactionState(element, cookies, count, state, index, offset) \ 1830 for (index = offset; index < count; index++) { \ 1831 element = GetElement(cookies[index]); \ 1832 if (element == NULL) \ 1833 continue; \ 1834 element->setTransactionState (state); \ 1835 } 1836 1837//--------------------------------------------------------------------------- 1838// Update the value of the given element, by getting a report from 1839// the device. Assume that the cookieCount > 0 1840 1841OSMetaClassDefineReservedUsed(IOHIDDevice, 0); 1842IOReturn IOHIDDevice::updateElementValues(IOHIDElementCookie *cookies, UInt32 cookieCount) { 1843 IOMemoryDescriptor * report = NULL; 1844 IOHIDElementPrivate * element = NULL; 1845 IOHIDReportType reportType; 1846 IOByteCount maxReportLength; 1847 UInt8 reportID; 1848 UInt32 index; 1849 IOReturn ret = kIOReturnError; 1850 1851 maxReportLength = max(_maxOutputReportSize, 1852 max(_maxFeatureReportSize, _maxInputReportSize)); 1853 1854 // Allocate a mem descriptor with the maxReportLength. 1855 // This way, we only have to allocate one mem discriptor 1856 report = IOBufferMemoryDescriptor::withCapacity(maxReportLength, kIODirectionNone); 1857 1858 if (report == NULL) 1859 return kIOReturnNoMemory; 1860 1861 ELEMENT_LOCK; 1862 1863 SetCookiesTransactionState(element, cookies, 1864 cookieCount, kIOHIDTransactionStatePending, index, 0); 1865 1866 // Iterate though all the elements in the 1867 // transaction. Generate reports if needed. 1868 for (index = 0; index < cookieCount; index++) { 1869 element = GetElement(cookies[index]); 1870 1871 if (element == NULL) 1872 continue; 1873 1874 if ( element->getTransactionState() 1875 != kIOHIDTransactionStatePending ) 1876 continue; 1877 1878 if ( !element->getReportType(&reportType) ) 1879 continue; 1880 1881 reportID = element->getReportID(); 1882 1883 // calling down into our subclass, so lets unlock 1884 ELEMENT_UNLOCK; 1885 1886 report->prepare(); 1887 ret = getReport(report, reportType, reportID); 1888 1889 ELEMENT_LOCK; 1890 1891 if (ret == kIOReturnSuccess) { 1892 // If we have a valid report, go ahead and process it. 1893 ret = handleReport(report, reportType, kIOHIDReportOptionNotInterrupt); 1894 } 1895 1896 report->complete(); 1897 1898 if (ret != kIOReturnSuccess) 1899 break; 1900 } 1901 1902 // release the report 1903 report->release(); 1904 1905 // If needed, set the transaction state for the 1906 // remaining elements to idle. 1907 SetCookiesTransactionState(element, cookies, 1908 cookieCount, kIOHIDTransactionStateIdle, index, 0); 1909 ELEMENT_UNLOCK; 1910 1911 return ret; 1912} 1913 1914//--------------------------------------------------------------------------- 1915// Post the value of the given element, by sending a report to 1916// the device. Assume that the cookieCount > 0 1917OSMetaClassDefineReservedUsed(IOHIDDevice, 1); 1918IOReturn IOHIDDevice::postElementValues(IOHIDElementCookie * cookies, UInt32 cookieCount) 1919{ 1920 IOBufferMemoryDescriptor *report = NULL; 1921 IOHIDElementPrivate *element = NULL; 1922 IOHIDElementPrivate *cookieElement = NULL; 1923 UInt8 *reportData = NULL; 1924 UInt32 maxReportLength = 0; 1925 UInt32 reportLength = 0; 1926 IOHIDReportType reportType; 1927 UInt8 reportID = 0; 1928 UInt32 index; 1929 IOReturn ret = kIOReturnError; 1930 1931 // Return an error if no cookies are being set 1932 if (cookieCount == 0) 1933 return ret; 1934 1935 // Get the max report size 1936 maxReportLength = max(_maxOutputReportSize, _maxFeatureReportSize); 1937 1938 // Allocate a buffer mem descriptor with the maxReportLength. 1939 // This way, we only have to allocate one mem buffer. 1940 report = IOBufferMemoryDescriptor::withCapacity(maxReportLength, kIODirectionNone); 1941 1942 if ( report == NULL ) 1943 return kIOReturnNoMemory; 1944 1945 ELEMENT_LOCK; 1946 1947 // Set the transaction state on the specified cookies 1948 SetCookiesTransactionState(cookieElement, cookies, 1949 cookieCount, kIOHIDTransactionStatePending, index, 0); 1950 1951 // Obtain the buffer 1952 reportData = (UInt8 *)report->getBytesNoCopy(); 1953 1954 // Iterate though all the elements in the 1955 // transaction. Generate reports if needed. 1956 for (index = 0; index < cookieCount; index ++) { 1957 1958 cookieElement = GetElement(cookies[index]); 1959 1960 if ( cookieElement == NULL ) 1961 continue; 1962 1963 // Continue on to the next element if 1964 // we've already processed this one 1965 if ( cookieElement->getTransactionState() 1966 != kIOHIDTransactionStatePending ) 1967 continue; 1968 1969 if ( !cookieElement->getReportType(&reportType) ) 1970 continue; 1971 1972 reportID = cookieElement->getReportID(); 1973 1974 // Start at the head element and iterate through 1975 element = GetHeadElement(GetReportHandlerSlot(reportID), reportType); 1976 1977 while ( element ) { 1978 1979 element->createReport(reportID, reportData, &reportLength, &element); 1980 1981 // If the reportLength was set, then this is 1982 // the head element for this report 1983 if ( reportLength ) { 1984 report->setLength(reportLength); 1985 reportLength = 0; 1986 } 1987 1988 } 1989 1990 // If there are multiple reports, append 1991 // the reportID to the first byte 1992 if ( _reportCount > 1 ) 1993 reportData[0] = reportID; 1994 1995 ELEMENT_UNLOCK; 1996 1997 report->prepare(); 1998 ret = setReport( report, reportType, reportID); 1999 report->complete(); 2000 2001 ELEMENT_LOCK; 2002 2003 if ( ret != kIOReturnSuccess ) 2004 break; 2005 } 2006 2007 // If needed, set the transaction state for the 2008 // remaining elements to idle. 2009 SetCookiesTransactionState(cookieElement, cookies, 2010 cookieCount, kIOHIDTransactionStateIdle, index, 0); 2011 2012 ELEMENT_UNLOCK; 2013 2014 if ( report ) 2015 report->release(); 2016 2017 return ret; 2018} 2019 2020OSMetaClassDefineReservedUsed(IOHIDDevice, 2); 2021OSString * IOHIDDevice::newSerialNumberString() const 2022{ 2023 OSString * string = 0; 2024 OSNumber * number = newSerialNumber(); 2025 2026 if ( number ) 2027 { 2028 char str[11]; 2029 snprintf(str, sizeof (str), "%d", number->unsigned32BitValue()); 2030 string = OSString::withCString(str); 2031 number->release(); 2032 } 2033 2034 return string; 2035} 2036 2037OSMetaClassDefineReservedUsed(IOHIDDevice, 3); 2038OSNumber * IOHIDDevice::newLocationIDNumber() const 2039{ 2040 return 0; 2041} 2042 2043//--------------------------------------------------------------------------- 2044// Get an async report from the device. 2045 2046OSMetaClassDefineReservedUsed(IOHIDDevice, 4); 2047IOReturn IOHIDDevice::getReport(IOMemoryDescriptor *report __unused, 2048 IOHIDReportType reportType __unused, 2049 IOOptionBits options __unused, 2050 UInt32 completionTimeout __unused, 2051 IOHIDCompletion *completion __unused) 2052{ 2053 return kIOReturnUnsupported; 2054} 2055 2056//--------------------------------------------------------------------------- 2057// Send an async report to the device. 2058 2059OSMetaClassDefineReservedUsed(IOHIDDevice, 5); 2060IOReturn IOHIDDevice::setReport(IOMemoryDescriptor *report __unused, 2061 IOHIDReportType reportType __unused, 2062 IOOptionBits options __unused, 2063 UInt32 completionTimeout __unused, 2064 IOHIDCompletion *completion __unused) 2065{ 2066 return kIOReturnUnsupported; 2067} 2068 2069//--------------------------------------------------------------------------- 2070// Return the vendor id source 2071 2072OSMetaClassDefineReservedUsed(IOHIDDevice, 6); 2073OSNumber * IOHIDDevice::newVendorIDSourceNumber() const 2074{ 2075 return 0; 2076} 2077 2078//--------------------------------------------------------------------------- 2079// Return the country code 2080 2081OSMetaClassDefineReservedUsed(IOHIDDevice, 7); 2082OSNumber * IOHIDDevice::newCountryCodeNumber() const 2083{ 2084 return 0; 2085} 2086 2087//--------------------------------------------------------------------------- 2088// Handle input reports (USB Interrupt In pipe) from the device. 2089 2090OSMetaClassDefineReservedUsed(IOHIDDevice, 8); 2091IOReturn IOHIDDevice::handleReportWithTime( 2092 AbsoluteTime timeStamp, 2093 IOMemoryDescriptor * report, 2094 IOHIDReportType reportType, 2095 IOOptionBits options) 2096{ 2097 void * reportData; 2098 IOByteCount reportLength; 2099 IOReturn ret = kIOReturnNotReady; 2100 bool changed = false; 2101 bool shouldTickle = false; 2102 UInt8 reportID = 0; 2103 2104 IOHID_DEBUG(kIOHIDDebugCode_HandleReport, reportType, options, __OSAbsoluteTime(timeStamp), getRegistryEntryID()); 2105 2106 if ((reportType == kIOHIDReportTypeInput) && !_readyForInputReports) 2107 return kIOReturnOffline; 2108 2109 // Get a pointer to the data in the descriptor. 2110 if ( !report ) 2111 return kIOReturnBadArgument; 2112 2113 reportLength = report->getLength(); 2114 2115 if ( !reportLength ) 2116 return kIOReturnBadArgument; 2117 2118 reportData = IOMalloc(reportLength); 2119 2120 if ( !reportData ) 2121 return kIOReturnNoMemory; 2122 2123 report->readBytes( 0, reportData, reportLength ); 2124 2125 ELEMENT_LOCK; 2126 2127 if ( _readyForInputReports ) { 2128 IOHIDElementPrivate * element; 2129 2130 // The first byte in the report, may be the report ID. 2131 // XXX - Do we need to advance the start of the report data? 2132 2133 reportID = ( _reportCount > 1 ) ? *((UInt8 *) reportData) : 0; 2134 2135 // Get the first element in the report handler chain. 2136 2137 element = GetHeadElement( GetReportHandlerSlot(reportID), 2138 reportType); 2139 2140 while ( element ) { 2141 shouldTickle |= element->shouldTickleActivity(); 2142 changed |= element->processReport( reportID, 2143 reportData, 2144 reportLength << 3, 2145 &timeStamp, 2146 &element, 2147 options ); 2148 } 2149 2150 ret = kIOReturnSuccess; 2151 } 2152 2153 if ( ( reportType == kIOHIDReportTypeInput ) && 2154 (( options & kIOHIDReportOptionNotInterrupt ) == 0 ) && _interfaceNub && !_seizedClient) { 2155 _interfaceNub->handleReport(timeStamp, report, reportType, reportID, options); 2156 } 2157 2158 ELEMENT_UNLOCK; 2159 2160 // Release the buffer 2161 IOFree(reportData, reportLength); 2162 2163 // RY: If this is a non-system HID device, post a null hid 2164 // event to prevent the system from sleeping. 2165 if (changed && shouldTickle && _performTickle 2166 && (CMP_ABSOLUTETIME(&timeStamp, &_eventDeadline) > 0)) 2167 { 2168 AbsoluteTime ts; 2169 2170 nanoseconds_to_absolutetime(kIOHIDEventThreshold, &ts); 2171 2172 _eventDeadline = ts; 2173 2174 ADD_ABSOLUTETIME(&_eventDeadline, &timeStamp); 2175 2176 IOHIDSystemActivityTickle(NX_NULLEVENT, this); 2177 } 2178 2179 return ret; 2180} 2181 2182//--------------------------------------------------------------------------- 2183// Return the polling interval 2184 2185OSMetaClassDefineReservedUsed(IOHIDDevice, 9); 2186OSNumber * IOHIDDevice::newReportIntervalNumber() const 2187{ 2188 UInt32 interval = 8000; // default to 8 milliseconds 2189 OSNumber *number = (OSNumber*)copyProperty(kIOHIDReportIntervalKey, gIOServicePlane, kIORegistryIterateRecursively | kIORegistryIterateParents); 2190 if ( OSDynamicCast(OSNumber, number) ) 2191 interval = number->unsigned32BitValue(); 2192 OSSafeReleaseNULL(number); 2193 2194 return OSNumber::withNumber(interval, 32); 2195} 2196 2197//--------------------------------------------------------------------------- 2198// Asynchronously handle input reports 2199 2200OSMetaClassDefineReservedUsed(IOHIDDevice, 10); 2201IOReturn IOHIDDevice::handleReportWithTimeAsync( 2202 AbsoluteTime timeStamp, 2203 IOMemoryDescriptor * report, 2204 IOHIDReportType reportType, 2205 IOOptionBits options, 2206 UInt32 completionTimeout, 2207 IOHIDCompletion * completion) 2208{ 2209 IOReturn result = kIOReturnError; 2210 2211 if (!_asyncReportQueue) { 2212 _asyncReportQueue = IOHIDAsyncReportQueue::withOwner(this); 2213 2214 if (_asyncReportQueue) { 2215 /*status =*/ getWorkLoop()->addEventSource ( _asyncReportQueue ); 2216 } 2217 } 2218 2219 if (_asyncReportQueue) { 2220 result = _asyncReportQueue->postReport(timeStamp, report, reportType, options, completionTimeout, completion); 2221 } 2222 2223 return result; 2224} 2225 2226OSMetaClassDefineReservedUnused(IOHIDDevice, 12); 2227OSMetaClassDefineReservedUnused(IOHIDDevice, 13); 2228OSMetaClassDefineReservedUnused(IOHIDDevice, 14); 2229OSMetaClassDefineReservedUnused(IOHIDDevice, 15); 2230OSMetaClassDefineReservedUnused(IOHIDDevice, 16); 2231OSMetaClassDefineReservedUnused(IOHIDDevice, 17); 2232OSMetaClassDefineReservedUnused(IOHIDDevice, 18); 2233OSMetaClassDefineReservedUnused(IOHIDDevice, 19); 2234OSMetaClassDefineReservedUnused(IOHIDDevice, 20); 2235OSMetaClassDefineReservedUnused(IOHIDDevice, 21); 2236OSMetaClassDefineReservedUnused(IOHIDDevice, 22); 2237OSMetaClassDefineReservedUnused(IOHIDDevice, 23); 2238OSMetaClassDefineReservedUnused(IOHIDDevice, 24); 2239OSMetaClassDefineReservedUnused(IOHIDDevice, 25); 2240OSMetaClassDefineReservedUnused(IOHIDDevice, 26); 2241OSMetaClassDefineReservedUnused(IOHIDDevice, 27); 2242OSMetaClassDefineReservedUnused(IOHIDDevice, 28); 2243OSMetaClassDefineReservedUnused(IOHIDDevice, 29); 2244OSMetaClassDefineReservedUnused(IOHIDDevice, 30); 2245OSMetaClassDefineReservedUnused(IOHIDDevice, 31); 2246OSMetaClassDefineReservedUnused(IOHIDDevice, 32); 2247OSMetaClassDefineReservedUnused(IOHIDDevice, 33); 2248OSMetaClassDefineReservedUnused(IOHIDDevice, 34); 2249OSMetaClassDefineReservedUnused(IOHIDDevice, 35); 2250OSMetaClassDefineReservedUnused(IOHIDDevice, 36); 2251OSMetaClassDefineReservedUnused(IOHIDDevice, 37); 2252OSMetaClassDefineReservedUnused(IOHIDDevice, 38); 2253OSMetaClassDefineReservedUnused(IOHIDDevice, 39); 2254OSMetaClassDefineReservedUnused(IOHIDDevice, 40); 2255 2256