1/* 2 * Copyright (c) 2019-2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#if !__IIG 30#if KERNEL 31#include <IOKit/IOService.h> 32#endif 33#endif 34 35#ifndef _IOKIT_UIOSERVICE_H 36#define _IOKIT_UIOSERVICE_H 37 38#include <DriverKit/OSObject.iig> 39 40class IOMemoryDescriptor; 41class IOBufferMemoryDescriptor; 42class IOUserClient; 43class OSAction; 44class IOServiceStateNotificationDispatchSource; 45 46typedef char IOServiceName[128]; 47typedef char IOPropertyName[128]; 48typedef char IORegistryPlaneName[128]; 49 50enum { 51 kIOServiceSearchPropertyParents = 0x00000001, 52}; 53 54#define kIOServiceDefaultQueueName "Default" 55 56enum { 57 kIOServicePowerCapabilityOff = 0x00000000, 58 kIOServicePowerCapabilityOn = 0x00000002, 59 kIOServicePowerCapabilityLow = 0x00010000, 60 kIOServicePowerCapabilityLPW = 0x00020000, 61}; 62 63enum { 64 _kIOPMWakeEventSource = 0x00000001, 65 _kIOPMWakeEventFullWake = 0x00000002, 66 _kIOPMWakeEventPossibleFullWake = 0x00000004, 67}; 68 69// values for OSNumber kIOSystemStateHaltDescriptionKey:kIOSystemStateHaltDescriptionHaltStateKey 70enum { 71 kIOServiceHaltStatePowerOff = 0x00000001, 72 kIOServiceHaltStateRestart = 0x00000002, 73}; 74 75// Bitfields for CreatePMAssertion 76enum { 77 /*! kIOServicePMAssertionCPUBit 78 * When set, PM kernel will prefer to leave the CPU and core hardware 79 * running in "Dark Wake" state, instead of sleeping. 80 */ 81 kIOServicePMAssertionCPUBit = 0x001, 82 83 /*! kIOServicePMAssertionForceFullWakeupBit 84 * When set, the system will immediately do a full wakeup after going to sleep. 85 */ 86 kIOServicePMAssertionForceFullWakeupBit = 0x800, 87}; 88 89/*! 90 * @class IOService 91 * 92 * @abstract 93 * IOService represents an device or OS service in IOKit and DriverKit. 94 * 95 * @discussion 96 * IOKit provides driver lifecycle management through the IOService APIs. 97 * Drivers and devices are represented as subclasses of IOService. 98 * 99 100@iig implementation 101#include <DriverKit/IODispatchQueue.h> 102#include <DriverKit/IOUserClient.h> 103#include <DriverKit/IOServiceStateNotificationDispatchSource.h> 104@iig end 105*/ 106 107class KERNEL IOService : public OSObject 108{ 109public: 110 virtual bool 111 init() override; 112 113 virtual void 114 free() override; 115 116 /*! 117 * @brief First call made to a matched IOService. 118 * @discussion During matching IOKit will create an IOService object for successful matches. 119 * Start is the first call made to the new object. 120 * @param provider The IOService provider for the match. This should be OSRequiredCast to the expected class. 121 * The provider is retained by DriverKit for the duration of Start() and on successful Start() until 122 * IOService::Stop() is called. 123 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 124 */ 125 virtual kern_return_t 126 Start(IOService * provider) LOCAL; 127 128 /*! 129 * @brief Terminate access to provider. 130 * @discussion During termination IOKit will teardown any IOService objects attached to a terminated provider. 131 * Stop should quiesce all activity and when complete, pass the call to super. After calling super, the 132 * provider is no longer valid and this object will likely be freed. 133 * @param provider The IOService provider for being terminated, one previously passed to Start 134 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 135 */ 136 virtual kern_return_t 137 Stop(IOService * provider) LOCAL; 138 139 /*! @function ClientCrashed 140 * @discussion Notification for kernel objects of a client crash. 141 * @param client Attached client. 142 * @param options No options are currently defined. 143 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 144 */ 145 virtual kern_return_t 146 ClientCrashed(IOService * client, uint64_t options); 147 148 /*! 149 * @brief Obtain IOKit IORegistryEntryID. 150 * @param registryEntryID IORegistryEntryID for the IOKit object. 151 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 152 */ 153 virtual kern_return_t 154 GetRegistryEntryID(uint64_t * registryEntryID) LOCAL; 155 156 /*! 157 * @brief Set the IORegistryEntry name. 158 * @param name Name for the IOKit object. The c-string will be copied. 159 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 160 */ 161 virtual kern_return_t 162 SetName( 163 const IOServiceName name); 164 165 /*! 166 * @brief Start the matching process on the IOService object. 167 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 168 */ 169 virtual kern_return_t 170 RegisterService(); 171 172 /*! 173 * @brief Set the IODispatchQueue for a given name on the IOService. 174 * @param name Name for the queue. The name may be referenced by methods in the .iig class definition 175 * with the QUEUENAME() attribute to indicate the method must be invoked on that queue. If a method 176 * is invoked before the queue is set for the name, the default queue is used. A default queue is 177 * created by DriverKit for every new IOService object with the name kIOServiceDefaultQueueName. 178 * @param queue Queue to be associated with the name on this IOService. 179 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 180 */ 181 virtual kern_return_t 182 SetDispatchQueue( 183 const IODispatchQueueName name, 184 IODispatchQueue * queue) override LOCAL; 185 186 /*! 187 * @brief Obtain the IODispatchQueue for a given name on the IOService. 188 * @param name Name for the queue. 189 * @param queue Returned, retained queue or NULL. The caller should release this queue. 190 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 191 */ 192 virtual kern_return_t 193 CopyDispatchQueue( 194 const IODispatchQueueName name, 195 IODispatchQueue ** queue) override; 196 197 /*! 198 * @brief Create the default IODispatchQueue for an IOService. IOService::init() 199 * calls this to create its default queue. 200 * @param queue Returned, retained queue or NULL. 201 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 202 */ 203 virtual kern_return_t 204 CreateDefaultDispatchQueue( 205 IODispatchQueue ** queue) LOCAL; 206 207 /*! 208 * @brief Obtain the IOKit registry properties for the IOService. 209 * @param properties Returned, retained dictionary of properties or NULL. The caller should release this dictionary. 210 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 211 */ 212 virtual kern_return_t 213 CopyProperties( 214 OSDictionary ** properties); 215 216 /*! 217 * @brief Obtain the an IOKit registry properties from the service or one of its parents. 218 * @param name Name of the property as a c-string. 219 * @param plane Name of the registry plane to be searched, if the option kIOServiceSearchPropertyParents 220 * is used. 221 * @param options Pass kIOServiceSearchPropertyParents to search for the property in the IOService and all 222 * its parents in the IOKit registry. 223 * @param property Returned, retained property object or NULL. The caller should release this property. 224 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 225 */ 226 virtual kern_return_t 227 SearchProperty( 228 const IOPropertyName name, 229 const IORegistryPlaneName plane, 230 uint64_t options, 231 OSContainer ** property); 232 233 /*! 234 * @brief Send a dictionary of properties to an IOService. 235 * @discussion By default the method will fail. A DriverKit subclass or kernel class may implement this method. 236 * @param properties Dictionary of properties. 237 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 238 */ 239 virtual kern_return_t 240 SetProperties( 241 OSDictionary * properties); 242 243 /*! 244 * @brief Add an IOService created by Create() to the power manangement tree. 245 * @discussion IOService objects created by matching on a provider are always added to the power management tree. 246 * Any IOService created with the Create() API is not, but may be added by calling this method. 247 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 248 */ 249 virtual kern_return_t 250 JoinPMTree(void); 251 252 /*! 253 * @brief Notification of change in power state of a provider. 254 * @discussion DriverKit notifies of changes in power of a provider. The driver should make itself safe for 255 * the new state before passing the call to super. 256 * @param powerFlags The power capabilities of the new state. The values possible are: 257 * kIOServicePowerCapabilityOff the system will be entering sleep state 258 * kIOServicePowerCapabilityOn the device and system are fully powered 259 * kIOServicePowerCapabilityLow the device is in a reduced power state while the system is running 260 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 261 */ 262 virtual kern_return_t 263 SetPowerState( 264 uint32_t powerFlags) LOCAL; 265 266 /*! 267 * @brief Allow provider to enter a low power state. 268 * @discussion A driver may allow a device to enter a lower power state. 269 * @param powerFlags The power capabilities of the new state. The values possible are: 270 * kIOServicePowerCapabilityLow the device is in a reduced power state while the system is running 271 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 272 */ 273 virtual kern_return_t 274 ChangePowerState( 275 uint32_t powerFlags); 276 277 /*! 278 * @brief Request provider to create a power override. 279 * @discussion Allows a driver to ignore power desires of its children, similar to powerOverrideOnPriv in IOKit, enabling its power state to be governed solely by its own desire (set via IOService::ChangePowerState) 280 * @param enable Whether to enable or disable the power override. 281 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 282 */ 283 virtual kern_return_t 284 SetPowerOverride( 285 bool enable); 286 287 /*! 288 * @brief Request create a new user client for a client process. 289 * @discussion An application may request an IOUserClient be opened with the IOKit framework 290 * IOServiceOpen() call. The type parameter of that call is passed here. The driver should respond to 291 * the call by calling IOService::Create() with a plist entry describing the new user client object. 292 * @param type The type passed to IOServiceOpen(). 293 * @param userClient The object created by IOService::Create() 294 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 295 */ 296 virtual kern_return_t 297 NewUserClient( 298 uint32_t type, 299 IOUserClient ** userClient); 300 301 /*! 302 * @brief Request to create an IOService object from a plist property. 303 * @discussion An IOService interface or IOUserClient subclass may be created from a plist property of the driver. 304 * The plist should contain the following IOKit matching keys: 305 * IOClass - kernel class of IOUserUserClient 306 * IOUserClass - DriverKit class to be instantiated 307 * IOServiceDEXTEntitlements - Array of entitlements to be checked against a user client owning task 308 * @param provider The provider of the new object. 309 * @param propertiesKey The name of the properties dictionary in this IOService 310 * @param result The created object retained, to be released by the caller. 311 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 312 */ 313 virtual kern_return_t 314 Create( 315 IOService * provider, 316 const IOPropertyName propertiesKey, 317 IOService ** result) LOCAL; 318 319 /*! 320 * @brief Start an IOService termination. 321 * @discussion An IOService object created with Create() may be removed by calling Terminate(). 322 * The termination is asynchronous and will later call Stop() on the service. 323 * @param options No options are currently defined, pass zero. 324 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 325 */ 326 virtual kern_return_t 327 Terminate( 328 uint64_t options); 329 330 /*! 331 * @brief Obtain supportable properties describing the provider chain. 332 * @discussion Obtain supportable properties describing the provider chain. This will be a subset of registry 333 * properties the OS considers supportable. 334 * The array is ordered with a dictionary of properties for each entry in the provider chain from this 335 * service towards the root. 336 * @param propertyKeys If only certain property values are need, they may be passed in this array. 337 * @param properties Returned, retained array of dictionaries of properties or NULL. The caller should release 338 * this array. 339 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 340 */ 341 virtual kern_return_t 342 CopyProviderProperties( 343 OSArray * propertyKeys, 344 OSArray ** properties); 345 346 /*! 347 * @brief Reduce power saving modes in the system in order to provide decreased latency 348 * to hardware DMA requests. 349 * @discussion When the system enters lower power states DMA access to memory may be affected. 350 * The best way by far to handle this is to change how you schedule your time-critical DMA operations in 351 * your driver such that an occasional delay will not affect the proper functioning of your device. 352 * However, if this is not possible, your driver can inform power management when a time-critical transfer 353 * begins and ends so that the system will not enter the lowest power states during that time. To do this, 354 * pass a value to requireMaxBusStall that informs power management of the maximum memory access latency in 355 * nanoseconds that can be tolerated by the driver. This value is hardware dependent and is related to the 356 * amount of buffering available in the hardware. 357 * Supported values are given by the kIOMaxBusStall* enum in IOTypes.h 358 * Pass the largest value possible that works for your device. This will minimize power 359 * consumption and maximize battery life by still allowing some level of CPU power management. 360 * @param maxBusStall A value from the kIOMaxBusStall* enum in IOTypes.h 361 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 362 */ 363 virtual kern_return_t 364 RequireMaxBusStall( 365 uint64_t maxBusStall); 366 367 /*! @function AdjustBusy 368 * @discussion Adjust the busy state of this service by applying a delta to the current busy state. 369 * Adjusting the busy state of a service to or from zero will change the provider's busy state by one, in the same direction. 370 * @param delta The delta value to apply to the busy state. 371 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 372 */ 373 virtual kern_return_t 374 AdjustBusy(int32_t delta); 375 376 /*! @function GetBusyState 377 * @discussion Get the busy state of this service. 378 * @param busyState The returned busy state. 379 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 380 */ 381 virtual kern_return_t 382 GetBusyState(uint32_t *busyState); 383 384 /*! 385 * @brief Post an event to CoreAnalytics. 386 * @discussion Post an event to CoreAnalytics. See the CoreAnalytics documentation for 387 * details. 388 * @param options No options currently defined pass zero. 389 * @param eventName See the CoreAnalytics documentation for details. 390 * @param eventPayload See the CoreAnalytics documentation for details. 391 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 392 */ 393 virtual kern_return_t 394 CoreAnalyticsSendEvent( 395 uint64_t options, 396 OSString * eventName, 397 OSDictionary * eventPayload); 398 399 /*! @function IOCreatePropertyMatchingDictionary 400 * @abstract Construct a matching dictionary for property matching. 401 */ 402 static OSDictionary * 403 CreatePropertyMatchingDictionary(const char * key, OSObjectPtr value, OSDictionary * matching) LOCALONLY; 404 405 /*! @function IOCreatePropertyMatchingDictionary 406 * @abstract Construct a matching dictionary for property matching. 407 */ 408 static OSDictionary * 409 CreatePropertyMatchingDictionary(const char * key, const char * stringValue, OSDictionary * matching) LOCALONLY; 410 411 /*! @function IOCreateKernelClassMatchingDictionary 412 * @abstract Construct a matching dictionary for kernel class matching. 413 */ 414 static OSDictionary * 415 CreateKernelClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 416 417 /*! @function IOCreateKernelClassMatchingDictionary 418 * @abstract Construct a matching dictionary for kernel class matching. 419 */ 420 static OSDictionary * 421 CreateKernelClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 422 423 /*! @function IOCreateUserClassMatchingDictionary 424 * @abstract Construct a matching dictionary for user class matching. 425 */ 426 static OSDictionary * 427 CreateUserClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 428 429 /*! @function IOCreateUserClassMatchingDictionary 430 * @abstract Construct a matching dictionary for user class matching. 431 */ 432 static OSDictionary * 433 CreateUserClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 434 435 /*! @function IOCreateNameMatchingDictionary 436 * @abstract Construct a matching dictionary for IOService name matching. 437 */ 438 static OSDictionary * 439 CreateNameMatchingDictionary(OSString * serviceName, OSDictionary * matching) LOCALONLY; 440 441 /*! @function IOCreateNameMatchingDictionary 442 * @abstract Construct a matching dictionary for IOService name matching. 443 */ 444 static OSDictionary * 445 CreateNameMatchingDictionary(const char * serviceName, OSDictionary * matching) LOCALONLY; 446 447 /*! @function UpdateReport 448 * @abstract update an IOReporting subscription by reading out channel data. 449 */ 450 virtual IOReturn UpdateReport(OSData *channels, uint32_t action, 451 uint32_t *outElementCount, 452 uint64_t offset, uint64_t capacity, 453 IOMemoryDescriptor *buffer); 454 455 /*! @function ConfigureReport 456 * @abstract Configure an IOReporting subscription 457 * @discussion outCount is counting channels for enable,disable. It is counting 458 * elements for getDimensions 459 */ 460 virtual IOReturn ConfigureReport(OSData *channels, uint32_t action, uint32_t *outCount); 461 462 /*! @function SetLegend 463 * @abstract set IORLegend and IORLegendPublic ioreg properties on this service. 464 * @discussion For use by DriverKit userspace services, since they can't set 465 * registry properties directly. 466 */ 467 virtual IOReturn SetLegend(OSArray *legend, bool is_public); 468 469 /*! 470 * @brief Get the IORegistryEntry name. 471 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 472 */ 473 virtual kern_return_t 474 CopyName(OSString ** name); 475 476 /*! @function StringFromReturn 477 * @abstract Get a string description for an IOReturn value. 478 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 479 */ 480 virtual kern_return_t 481 StringFromReturn( 482 IOReturn retval, 483 OSString ** str); 484 485 virtual kern_return_t 486 _ClaimSystemWakeEvent( 487 IOService * device, 488 uint64_t flags, 489 const IOPropertyName reason, 490 OSContainer * details); 491 492#if PRIVATE_WIFI_ONLY 493 /*! 494 * @brief Optionally supported external method to set properties in this service. 495 * @param properties The properties to set. 496 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 497 */ 498 virtual kern_return_t 499 UserSetProperties(OSContainer * properties) LOCAL; 500 501 /*! 502 * @brief Send the kIOMessageServicePropertyChange message 503 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 504 */ 505 virtual kern_return_t 506 SendIOMessageServicePropertyChange(); 507 508 const char * 509 StringFromReturn( 510 IOReturn retval) LOCALONLY; 511 512#endif /* PRIVATE_WIFI_ONLY */ 513 514 /*! @function RemoveProperty 515 * @abstract Remove a property from the IOService. 516 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 517 */ 518 virtual kern_return_t 519 RemoveProperty(OSString * propertyName); 520 521 /*! @function GetProvider 522 * @abstract Get the provider of this IOService. 523 * @discussion The DriverKit runtime caches the provider passed to IOService::Start(IOService * provider). 524 * This method returns the cached object. 525 */ 526 IOService * 527 GetProvider() const LOCALONLY; 528 529 /*! 530 * @function CopySystemStateNotificationService 531 * @abstract Obtain the system state notification service. 532 * @param service Return IOService object with +1 retain count, to be released 533 * by the caller. 534 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 535 */ 536 virtual kern_return_t 537 CopySystemStateNotificationService(IOService ** service); 538 539 /*! 540 * @function StateNotificationItemCreate 541 * @abstract Create a state notification item. 542 * @param itemName name of the item. 543 * @param value initial value of the item. Can be set to NULL. 544 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 545 */ 546 virtual kern_return_t 547 StateNotificationItemCreate(OSString * itemName, OSDictionary * value); 548 549 /*! 550 * @function StateNotificationItemSet 551 * @abstract Set the value of a state notification item. 552 * @param itemName name of the item. 553 * @param value dictionary value for the item, item creator to define. 554 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 555 */ 556 virtual kern_return_t 557 StateNotificationItemSet(OSString * itemName, OSDictionary * value); 558 559 /*! 560 * @function StateNotificationItemCopy 561 * @abstract Set the value of a state notification item. 562 * @param itemName name of the item. 563 * @param value dictionary value for the item, item creator to define. 564 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 565 */ 566 virtual kern_return_t 567 StateNotificationItemCopy(OSString * itemName, OSDictionary ** value); 568 569 /*! 570 * @function CreatePMAssertion 571 * @abstract Create a power management assertion. 572 * @param assertionBits Bit masks including all the flavors that require to be asserted. 573 * @param assertionID pointer that will contain the unique identifier of the created 574 * power assertion. 575 * @param synced indicates if the assertion must prevent an imminent sleep transition. 576 * When set to true, and if a system sleep is irreversible, the call will return 577 * kIOReturnBusy, in which case the assertion is not created. Only 578 * kIOServicePMAssertionCPUBit is valid for assertionBits if sleepSafe is set to 579 * true. 580 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 581 */ 582 virtual kern_return_t 583 CreatePMAssertion(uint32_t assertionBits, uint64_t * assertionID, bool synced); 584 585 /*! 586 * @function ReleasePMAssertion 587 * @abstract Release a previously created power management assertion. 588 * @param assertionID the assertion ID returned by CreatePMAssertion. 589 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 590 */ 591 virtual kern_return_t 592 ReleasePMAssertion(uint64_t assertionID); 593 594private: 595 virtual void 596 Stop_async( 597 IOService * provider) LOCAL; 598 599 virtual kern_return_t 600 _NewUserClient( 601 uint32_t type, 602 OSDictionary * entitlements, 603 IOUserClient ** userClient) LOCAL; 604}; 605 606#endif /* ! _IOKIT_UIOSERVICE_H */ 607