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}; 61 62enum { 63 _kIOPMWakeEventSource = 0x00000001, 64}; 65 66// values for OSNumber kIOSystemStateHaltDescriptionKey:kIOSystemStateHaltDescriptionHaltStateKey 67enum { 68 kIOServiceHaltStatePowerOff = 0x00000001, 69 kIOServiceHaltStateRestart = 0x00000002, 70}; 71 72/*! 73 * @class IOService 74 * 75 * @abstract 76 * IOService represents an device or OS service in IOKit and DriverKit. 77 * 78 * @discussion 79 * IOKit provides driver lifecycle management through the IOService APIs. 80 * Drivers and devices are represented as subclasses of IOService. 81 * 82 83@iig implementation 84#include <DriverKit/IODispatchQueue.h> 85#include <DriverKit/IOUserClient.h> 86#include <DriverKit/IOServiceStateNotificationDispatchSource.h> 87@iig end 88*/ 89 90class KERNEL IOService : public OSObject 91{ 92public: 93 virtual bool 94 init() override; 95 96 virtual void 97 free() override; 98 99 /*! 100 * @brief First call made to a matched IOService. 101 * @discussion During matching IOKit will create an IOService object for successful matches. 102 * Start is the first call made to the new object. 103 * @param provider The IOService provider for the match. This should be OSRequiredCast to the expected class. 104 * The provider is retained by DriverKit for the duration of Start() and on successful Start() until 105 * IOService::Stop() is called. 106 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 107 */ 108 virtual kern_return_t 109 Start(IOService * provider) LOCAL; 110 111 /*! 112 * @brief Terminate access to provider. 113 * @discussion During termination IOKit will teardown any IOService objects attached to a terminated provider. 114 * Stop should quiesce all activity and when complete, pass the call to super. After calling super, the 115 * provider is no longer valid and this object will likely be freed. 116 * @param provider The IOService provider for being terminated, one previously passed to Start 117 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 118 */ 119 virtual kern_return_t 120 Stop(IOService * provider) LOCAL; 121 122 /*! @function ClientCrashed 123 * @discussion Notification for kernel objects of a client crash. 124 * @param client Attached client. 125 * @param options No options are currently defined. 126 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 127 */ 128 virtual kern_return_t 129 ClientCrashed(IOService * client, uint64_t options); 130 131 /*! 132 * @brief Obtain IOKit IORegistryEntryID. 133 * @param registryEntryID IORegistryEntryID for the IOKit object. 134 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 135 */ 136 virtual kern_return_t 137 GetRegistryEntryID(uint64_t * registryEntryID) LOCAL; 138 139 /*! 140 * @brief Set the IORegistryEntry name. 141 * @param name Name for the IOKit object. The c-string will be copied. 142 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 143 */ 144 virtual kern_return_t 145 SetName( 146 const IOServiceName name); 147 148 /*! 149 * @brief Start the matching process on the IOService object. 150 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 151 */ 152 virtual kern_return_t 153 RegisterService(); 154 155 /*! 156 * @brief Set the IODispatchQueue for a given name on the IOService. 157 * @param name Name for the queue. The name may be referenced by methods in the .iig class definition 158 * with the QUEUENAME() attribute to indicate the method must be invoked on that queue. If a method 159 * is invoked before the queue is set for the name, the default queue is used. A default queue is 160 * created by DriverKit for every new IOService object with the name kIOServiceDefaultQueueName. 161 * @param queue Queue to be associated with the name on this IOService. 162 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 163 */ 164 virtual kern_return_t 165 SetDispatchQueue( 166 const IODispatchQueueName name, 167 IODispatchQueue * queue) override LOCAL; 168 169 /*! 170 * @brief Obtain the IODispatchQueue for a given name on the IOService. 171 * @param name Name for the queue. 172 * @param queue Returned, retained queue or NULL. The caller should release this queue. 173 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 174 */ 175 virtual kern_return_t 176 CopyDispatchQueue( 177 const IODispatchQueueName name, 178 IODispatchQueue ** queue) override; 179 180 /*! 181 * @brief Create the default IODispatchQueue for an IOService. IOService::init() 182 * calls this to create its default queue. 183 * @param queue Returned, retained queue or NULL. 184 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 185 */ 186 virtual kern_return_t 187 CreateDefaultDispatchQueue( 188 IODispatchQueue ** queue) LOCAL; 189 190 /*! 191 * @brief Obtain the IOKit registry properties for the IOService. 192 * @param properties Returned, retained dictionary of properties or NULL. The caller should release this dictionary. 193 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 194 */ 195 virtual kern_return_t 196 CopyProperties( 197 OSDictionary ** properties); 198 199 /*! 200 * @brief Obtain the an IOKit registry properties from the service or one of its parents. 201 * @param name Name of the property as a c-string. 202 * @param plane Name of the registry plane to be searched, if the option kIOServiceSearchPropertyParents 203 * is used. 204 * @param options Pass kIOServiceSearchPropertyParents to search for the property in the IOService and all 205 * its parents in the IOKit registry. 206 * @param property Returned, retained property object or NULL. The caller should release this property. 207 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 208 */ 209 virtual kern_return_t 210 SearchProperty( 211 const IOPropertyName name, 212 const IORegistryPlaneName plane, 213 uint64_t options, 214 OSContainer ** property); 215 216 /*! 217 * @brief Send a dictionary of properties to an IOService. 218 * @discussion By default the method will fail. A DriverKit subclass or kernel class may implement this method. 219 * @param properties Dictionary of properties. 220 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 221 */ 222 virtual kern_return_t 223 SetProperties( 224 OSDictionary * properties); 225 226 /*! 227 * @brief Add an IOService created by Create() to the power manangement tree. 228 * @discussion IOService objects created by matching on a provider are always added to the power management tree. 229 * Any IOService created with the Create() API is not, but may be added by calling this method. 230 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 231 */ 232 virtual kern_return_t 233 JoinPMTree(void); 234 235 /*! 236 * @brief Notification of change in power state of a provider. 237 * @discussion DriverKit notifies of changes in power of a provider. The driver should make itself safe for 238 * the new state before passing the call to super. 239 * @param powerFlags The power capabilities of the new state. The values possible are: 240 * kIOServicePowerCapabilityOff the system will be entering sleep state 241 * kIOServicePowerCapabilityOn the device and system are fully powered 242 * kIOServicePowerCapabilityLow the device is in a reduced power state while the system is running 243 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 244 */ 245 virtual kern_return_t 246 SetPowerState( 247 uint32_t powerFlags) LOCAL; 248 249 /*! 250 * @brief Allow provider to enter a low power state. 251 * @discussion A driver may allow a device to enter a lower power state. 252 * @param powerFlags The power capabilities of the new state. The values possible are: 253 * kIOServicePowerCapabilityLow the device is in a reduced power state while the system is running 254 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 255 */ 256 virtual kern_return_t 257 ChangePowerState( 258 uint32_t powerFlags); 259 260 /*! 261 * @brief Request provider to create a power override. 262 * @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) 263 * @param enable Whether to enable or disable the power override. 264 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 265 */ 266 virtual kern_return_t 267 SetPowerOverride( 268 bool enable); 269 270 /*! 271 * @brief Request create a new user client for a client process. 272 * @discussion An application may request an IOUserClient be opened with the IOKit framework 273 * IOServiceOpen() call. The type parameter of that call is passed here. The driver should respond to 274 * the call by calling IOService::Create() with a plist entry describing the new user client object. 275 * @param type The type passed to IOServiceOpen(). 276 * @param userClient The object created by IOService::Create() 277 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 278 */ 279 virtual kern_return_t 280 NewUserClient( 281 uint32_t type, 282 IOUserClient ** userClient); 283 284 /*! 285 * @brief Request to create an IOService object from a plist property. 286 * @discussion An IOService interface or IOUserClient subclass may be created from a plist property of the driver. 287 * The plist should contain the following IOKit matching keys: 288 * IOClass - kernel class of IOUserUserClient 289 * IOUserClass - DriverKit class to be instantiated 290 * IOServiceDEXTEntitlements - Array of entitlements to be checked against a user client owning task 291 * @param provider The provider of the new object. 292 * @param propertiesKey The name of the properties dictionary in this IOService 293 * @param result The created object retained, to be released by the caller. 294 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 295 */ 296 virtual kern_return_t 297 Create( 298 IOService * provider, 299 const IOPropertyName propertiesKey, 300 IOService ** result) LOCAL; 301 302 /*! 303 * @brief Start an IOService termination. 304 * @discussion An IOService object created with Create() may be removed by calling Terminate(). 305 * The termination is asynchronous and will later call Stop() on the service. 306 * @param options No options are currently defined, pass zero. 307 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 308 */ 309 virtual kern_return_t 310 Terminate( 311 uint64_t options); 312 313 /*! 314 * @brief Obtain supportable properties describing the provider chain. 315 * @discussion Obtain supportable properties describing the provider chain. This will be a subset of registry 316 * properties the OS considers supportable. 317 * The array is ordered with a dictionary of properties for each entry in the provider chain from this 318 * service towards the root. 319 * @param propertyKeys If only certain property values are need, they may be passed in this array. 320 * @param properties Returned, retained array of dictionaries of properties or NULL. The caller should release 321 * this array. 322 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 323 */ 324 virtual kern_return_t 325 CopyProviderProperties( 326 OSArray * propertyKeys, 327 OSArray ** properties); 328 329 /*! 330 * @brief Reduce power saving modes in the system in order to provide decreased latency 331 * to hardware DMA requests. 332 * @discussion When the system enters lower power states DMA access to memory may be affected. 333 * The best way by far to handle this is to change how you schedule your time-critical DMA operations in 334 * your driver such that an occasional delay will not affect the proper functioning of your device. 335 * However, if this is not possible, your driver can inform power management when a time-critical transfer 336 * begins and ends so that the system will not enter the lowest power states during that time. To do this, 337 * pass a value to requireMaxBusStall that informs power management of the maximum memory access latency in 338 * nanoseconds that can be tolerated by the driver. This value is hardware dependent and is related to the 339 * amount of buffering available in the hardware. 340 * Supported values are given by the kIOMaxBusStall* enum in IOTypes.h 341 * Pass the largest value possible that works for your device. This will minimize power 342 * consumption and maximize battery life by still allowing some level of CPU power management. 343 * @param maxBusStall A value from the kIOMaxBusStall* enum in IOTypes.h 344 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 345 */ 346 virtual kern_return_t 347 RequireMaxBusStall( 348 uint64_t maxBusStall); 349 350 /*! @function AdjustBusy 351 * @discussion Adjust the busy state of this service by applying a delta to the current busy state. 352 * Adjusting the busy state of a service to or from zero will change the provider's busy state by one, in the same direction. 353 * @param delta The delta value to apply to the busy state. 354 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 355 */ 356 virtual kern_return_t 357 AdjustBusy(int32_t delta); 358 359 /*! @function GetBusyState 360 * @discussion Get the busy state of this service. 361 * @param busyState The returned busy state. 362 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 363 */ 364 virtual kern_return_t 365 GetBusyState(uint32_t *busyState); 366 367 /*! 368 * @brief Post an event to CoreAnalytics. 369 * @discussion Post an event to CoreAnalytics. See the CoreAnalytics documentation for 370 * details. 371 * @param options No options currently defined pass zero. 372 * @param eventName See the CoreAnalytics documentation for details. 373 * @param eventPayload See the CoreAnalytics documentation for details. 374 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 375 */ 376 virtual kern_return_t 377 CoreAnalyticsSendEvent( 378 uint64_t options, 379 OSString * eventName, 380 OSDictionary * eventPayload); 381 382 /*! @function IOCreatePropertyMatchingDictionary 383 * @abstract Construct a matching dictionary for property matching. 384 */ 385 static OSDictionary * 386 CreatePropertyMatchingDictionary(const char * key, OSObjectPtr value, OSDictionary * matching) LOCALONLY; 387 388 /*! @function IOCreatePropertyMatchingDictionary 389 * @abstract Construct a matching dictionary for property matching. 390 */ 391 static OSDictionary * 392 CreatePropertyMatchingDictionary(const char * key, const char * stringValue, OSDictionary * matching) LOCALONLY; 393 394 /*! @function IOCreateKernelClassMatchingDictionary 395 * @abstract Construct a matching dictionary for kernel class matching. 396 */ 397 static OSDictionary * 398 CreateKernelClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 399 400 /*! @function IOCreateKernelClassMatchingDictionary 401 * @abstract Construct a matching dictionary for kernel class matching. 402 */ 403 static OSDictionary * 404 CreateKernelClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 405 406 /*! @function IOCreateUserClassMatchingDictionary 407 * @abstract Construct a matching dictionary for user class matching. 408 */ 409 static OSDictionary * 410 CreateUserClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 411 412 /*! @function IOCreateUserClassMatchingDictionary 413 * @abstract Construct a matching dictionary for user class matching. 414 */ 415 static OSDictionary * 416 CreateUserClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 417 418 /*! @function IOCreateNameMatchingDictionary 419 * @abstract Construct a matching dictionary for IOService name matching. 420 */ 421 static OSDictionary * 422 CreateNameMatchingDictionary(OSString * serviceName, OSDictionary * matching) LOCALONLY; 423 424 /*! @function IOCreateNameMatchingDictionary 425 * @abstract Construct a matching dictionary for IOService name matching. 426 */ 427 static OSDictionary * 428 CreateNameMatchingDictionary(const char * serviceName, OSDictionary * matching) LOCALONLY; 429 430 /*! @function UpdateReport 431 * @abstract update an IOReporting subscription by reading out channel data. 432 */ 433 virtual IOReturn UpdateReport(OSData *channels, uint32_t action, 434 uint32_t *outElementCount, 435 uint64_t offset, uint64_t capacity, 436 IOMemoryDescriptor *buffer); 437 438 /*! @function ConfigureReport 439 * @abstract Configure an IOReporting subscription 440 * @discussion outCount is counting channels for enable,disable. It is counting 441 * elements for getDimensions 442 */ 443 virtual IOReturn ConfigureReport(OSData *channels, uint32_t action, uint32_t *outCount); 444 445 /*! @function SetLegend 446 * @abstract set IORLegend and IORLegendPublic ioreg properties on this service. 447 * @discussion For use by DriverKit userspace services, since they can't set 448 * registry properties directly. 449 */ 450 virtual IOReturn SetLegend(OSArray *legend, bool is_public); 451 452 /*! 453 * @brief Get the IORegistryEntry name. 454 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 455 */ 456 virtual kern_return_t 457 CopyName(OSString ** name); 458 459 /*! @function StringFromReturn 460 * @abstract Get a string description for an IOReturn value. 461 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 462 */ 463 virtual kern_return_t 464 StringFromReturn( 465 IOReturn retval, 466 OSString ** str); 467 468 virtual kern_return_t 469 _ClaimSystemWakeEvent( 470 IOService * device, 471 uint64_t flags, 472 const IOPropertyName reason, 473 OSContainer * details); 474 475#if PRIVATE_WIFI_ONLY 476 /*! 477 * @brief Optionally supported external method to set properties in this service. 478 * @param properties The properties to set. 479 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 480 */ 481 virtual kern_return_t 482 UserSetProperties(OSContainer * properties) LOCAL; 483 484 /*! 485 * @brief Send the kIOMessageServicePropertyChange message 486 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 487 */ 488 virtual kern_return_t 489 SendIOMessageServicePropertyChange(); 490 491 const char * 492 StringFromReturn( 493 IOReturn retval) LOCALONLY; 494#endif /* PRIVATE_WIFI_ONLY */ 495 496 /*! @function RemoveProperty 497 * @abstract Remove a property from the IOService. 498 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 499 */ 500 virtual kern_return_t 501 RemoveProperty(OSString * propertyName); 502 503 /*! @function GetProvider 504 * @abstract Get the provider of this IOService. 505 * @discussion The DriverKit runtime caches the provider passed to IOService::Start(IOService * provider). 506 * This method returns the cached object. 507 */ 508 IOService * 509 GetProvider() const LOCALONLY; 510 511 /*! 512 * @function CopySystemStateNotificationService 513 * @abstract Obtain the system state notification service. 514 * @param service Return IOService object with +1 retain count, to be released 515 * by the caller. 516 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 517 */ 518 virtual kern_return_t 519 CopySystemStateNotificationService(IOService ** service); 520 521 /*! 522 * @function StateNotificationItemCreate 523 * @abstract Create a state notification item. 524 * @param itemName name of the item. 525 * @param schema dictionary describing behaviors for the item. Keys are defined in 526 * IOKitKeys.h kIOStateNotification* 527 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 528 */ 529 virtual kern_return_t 530 StateNotificationItemCreate(OSString * itemName, OSDictionary * schema); 531 532 /*! 533 * @function StateNotificationItemSet 534 * @abstract Set the value of a state notification item. 535 * @param itemName name of the item. 536 * @param value dictionary value for the item, item creator to define. 537 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 538 */ 539 virtual kern_return_t 540 StateNotificationItemSet(OSString * itemName, OSDictionary * value); 541 542 /*! 543 * @function StateNotificationItemCopy 544 * @abstract Set the value of a state notification item. 545 * @param itemName name of the item. 546 * @param value dictionary value for the item, item creator to define. 547 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 548 */ 549 virtual kern_return_t 550 StateNotificationItemCopy(OSString * itemName, OSDictionary ** value); 551 552private: 553 virtual void 554 Stop_async( 555 IOService * provider) LOCAL; 556 557 virtual kern_return_t 558 _NewUserClient( 559 uint32_t type, 560 OSDictionary * entitlements, 561 IOUserClient ** userClient) LOCAL; 562}; 563 564#endif /* ! _IOKIT_UIOSERVICE_H */ 565