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 create a new user client for a client process. 262 * @discussion An application may request an IOUserClient be opened with the IOKit framework 263 * IOServiceOpen() call. The type parameter of that call is passed here. The driver should respond to 264 * the call by calling IOService::Create() with a plist entry describing the new user client object. 265 * @param type The type passed to IOServiceOpen(). 266 * @param userClient The object created by IOService::Create() 267 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 268 */ 269 virtual kern_return_t 270 NewUserClient( 271 uint32_t type, 272 IOUserClient ** userClient); 273 274 /*! 275 * @brief Request to create an IOService object from a plist property. 276 * @discussion An IOService interface or IOUserClient subclass may be created from a plist property of the driver. 277 * The plist should contain the following IOKit matching keys: 278 * IOClass - kernel class of IOUserUserClient 279 * IOUserClass - DriverKit class to be instantiated 280 * IOServiceDEXTEntitlements - Array of entitlements to be checked against a user client owning task 281 * @param provider The provider of the new object. 282 * @param propertiesKey The name of the properties dictionary in this IOService 283 * @param result The created object retained, to be released by the caller. 284 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 285 */ 286 virtual kern_return_t 287 Create( 288 IOService * provider, 289 const IOPropertyName propertiesKey, 290 IOService ** result) LOCAL; 291 292 /*! 293 * @brief Start an IOService termination. 294 * @discussion An IOService object created with Create() may be removed by calling Terminate(). 295 * The termination is asynchronous and will later call Stop() on the service. 296 * @param options No options are currently defined, pass zero. 297 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 298 */ 299 virtual kern_return_t 300 Terminate( 301 uint64_t options); 302 303 /*! 304 * @brief Obtain supportable properties describing the provider chain. 305 * @discussion Obtain supportable properties describing the provider chain. This will be a subset of registry 306 * properties the OS considers supportable. 307 * The array is ordered with a dictionary of properties for each entry in the provider chain from this 308 * service towards the root. 309 * @param propertyKeys If only certain property values are need, they may be passed in this array. 310 * @param properties Returned, retained array of dictionaries of properties or NULL. The caller should release 311 * this array. 312 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 313 */ 314 virtual kern_return_t 315 CopyProviderProperties( 316 OSArray * propertyKeys, 317 OSArray ** properties); 318 319 /*! 320 * @brief Reduce power saving modes in the system in order to provide decreased latency 321 * to hardware DMA requests. 322 * @discussion When the system enters lower power states DMA access to memory may be affected. 323 * The best way by far to handle this is to change how you schedule your time-critical DMA operations in 324 * your driver such that an occasional delay will not affect the proper functioning of your device. 325 * However, if this is not possible, your driver can inform power management when a time-critical transfer 326 * begins and ends so that the system will not enter the lowest power states during that time. To do this, 327 * pass a value to requireMaxBusStall that informs power management of the maximum memory access latency in 328 * nanoseconds that can be tolerated by the driver. This value is hardware dependent and is related to the 329 * amount of buffering available in the hardware. 330 * Supported values are given by the kIOMaxBusStall* enum in IOTypes.h 331 * Pass the largest value possible that works for your device. This will minimize power 332 * consumption and maximize battery life by still allowing some level of CPU power management. 333 * @param maxBusStall A value from the kIOMaxBusStall* enum in IOTypes.h 334 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 335 */ 336 virtual kern_return_t 337 RequireMaxBusStall( 338 uint64_t maxBusStall); 339 340 /*! @function AdjustBusy 341 * @discussion Adjust the busy state of this service by applying a delta to the current busy state. 342 * Adjusting the busy state of a service to or from zero will change the provider's busy state by one, in the same direction. 343 * @param delta The delta value to apply to the busy state. 344 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 345 */ 346 virtual kern_return_t 347 AdjustBusy(int32_t delta); 348 349 /*! @function GetBusyState 350 * @discussion Get the busy state of this service. 351 * @param busyState The returned busy state. 352 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 353 */ 354 virtual kern_return_t 355 GetBusyState(uint32_t *busyState); 356 357 /*! 358 * @brief Post an event to CoreAnalytics. 359 * @discussion Post an event to CoreAnalytics. See the CoreAnalytics documentation for 360 * details. 361 * @param options No options currently defined pass zero. 362 * @param eventName See the CoreAnalytics documentation for details. 363 * @param eventPayload See the CoreAnalytics documentation for details. 364 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 365 */ 366 virtual kern_return_t 367 CoreAnalyticsSendEvent( 368 uint64_t options, 369 OSString * eventName, 370 OSDictionary * eventPayload); 371 372 /*! @function IOCreatePropertyMatchingDictionary 373 * @abstract Construct a matching dictionary for property matching. 374 */ 375 static OSDictionary * 376 CreatePropertyMatchingDictionary(const char * key, OSObjectPtr value, OSDictionary * matching) LOCALONLY; 377 378 /*! @function IOCreatePropertyMatchingDictionary 379 * @abstract Construct a matching dictionary for property matching. 380 */ 381 static OSDictionary * 382 CreatePropertyMatchingDictionary(const char * key, const char * stringValue, OSDictionary * matching) LOCALONLY; 383 384 /*! @function IOCreateKernelClassMatchingDictionary 385 * @abstract Construct a matching dictionary for kernel class matching. 386 */ 387 static OSDictionary * 388 CreateKernelClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 389 390 /*! @function IOCreateKernelClassMatchingDictionary 391 * @abstract Construct a matching dictionary for kernel class matching. 392 */ 393 static OSDictionary * 394 CreateKernelClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 395 396 /*! @function IOCreateUserClassMatchingDictionary 397 * @abstract Construct a matching dictionary for user class matching. 398 */ 399 static OSDictionary * 400 CreateUserClassMatchingDictionary(OSString * className, OSDictionary * matching) LOCALONLY; 401 402 /*! @function IOCreateUserClassMatchingDictionary 403 * @abstract Construct a matching dictionary for user class matching. 404 */ 405 static OSDictionary * 406 CreateUserClassMatchingDictionary(const char * className, OSDictionary * matching) LOCALONLY; 407 408 /*! @function IOCreateNameMatchingDictionary 409 * @abstract Construct a matching dictionary for IOService name matching. 410 */ 411 static OSDictionary * 412 CreateNameMatchingDictionary(OSString * serviceName, OSDictionary * matching) LOCALONLY; 413 414 /*! @function IOCreateNameMatchingDictionary 415 * @abstract Construct a matching dictionary for IOService name matching. 416 */ 417 static OSDictionary * 418 CreateNameMatchingDictionary(const char * serviceName, OSDictionary * matching) LOCALONLY; 419 420 /*! @function UpdateReport 421 * @abstract update an IOReporting subscription by reading out channel data. 422 */ 423 virtual IOReturn UpdateReport(OSData *channels, uint32_t action, 424 uint32_t *outElementCount, 425 uint64_t offset, uint64_t capacity, 426 IOMemoryDescriptor *buffer); 427 428 /*! @function ConfigureReport 429 * @abstract Configure an IOReporting subscription 430 * @discussion outCount is counting channels for enable,disable. It is counting 431 * elements for getDimensions 432 */ 433 virtual IOReturn ConfigureReport(OSData *channels, uint32_t action, uint32_t *outCount); 434 435 /*! @function SetLegend 436 * @abstract set IORLegend and IORLegendPublic ioreg properties on this service. 437 * @discussion For use by DriverKit userspace services, since they can't set 438 * registry properties directly. 439 */ 440 virtual IOReturn SetLegend(OSArray *legend, bool is_public); 441 442 /*! 443 * @brief Get the IORegistryEntry name. 444 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 445 */ 446 virtual kern_return_t 447 CopyName(OSString ** name); 448 449 /*! @function StringFromReturn 450 * @abstract Get a string description for an IOReturn value. 451 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 452 */ 453 virtual kern_return_t 454 StringFromReturn( 455 IOReturn retval, 456 OSString ** str); 457 458 virtual kern_return_t 459 _ClaimSystemWakeEvent( 460 IOService * device, 461 uint64_t flags, 462 const IOPropertyName reason, 463 OSContainer * details); 464 465#if PRIVATE_WIFI_ONLY 466 /*! 467 * @brief Optionally supported external method to set properties in this service. 468 * @param properties The properties to set. 469 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 470 */ 471 virtual kern_return_t 472 UserSetProperties(OSContainer * properties) LOCAL; 473 474 /*! 475 * @brief Send the kIOMessageServicePropertyChange message 476 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 477 */ 478 virtual kern_return_t 479 SendIOMessageServicePropertyChange(); 480 481 const char * 482 StringFromReturn( 483 IOReturn retval) LOCALONLY; 484#endif /* PRIVATE_WIFI_ONLY */ 485 486 /*! @function RemoveProperty 487 * @abstract Remove a property from the IOService. 488 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 489 */ 490 virtual kern_return_t 491 RemoveProperty(OSString * propertyName); 492 493 /*! @function GetProvider 494 * @abstract Get the provider of this IOService. 495 * @discussion The DriverKit runtime caches the provider passed to IOService::Start(IOService * provider). 496 * This method returns the cached object. 497 */ 498 IOService * 499 GetProvider() const LOCALONLY; 500 501 /*! 502 * @function CopySystemStateNotificationService 503 * @abstract Obtain the system state notification service. 504 * @param service Return IOService object with +1 retain count, to be released 505 * by the caller. 506 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 507 */ 508 virtual kern_return_t 509 CopySystemStateNotificationService(IOService ** service); 510 511 /*! 512 * @function StateNotificationItemCreate 513 * @abstract Create a state notification item. 514 * @param itemName name of the item. 515 * @param schema dictionary describing behaviors for the item. Keys are defined in 516 * IOKitKeys.h kIOStateNotification* 517 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 518 */ 519 virtual kern_return_t 520 StateNotificationItemCreate(OSString * itemName, OSDictionary * schema); 521 522 /*! 523 * @function StateNotificationItemSet 524 * @abstract Set the value of a state notification item. 525 * @param itemName name of the item. 526 * @param value dictionary value for the item, item creator to define. 527 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 528 */ 529 virtual kern_return_t 530 StateNotificationItemSet(OSString * itemName, OSDictionary * value); 531 532 /*! 533 * @function StateNotificationItemCopy 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 StateNotificationItemCopy(OSString * itemName, OSDictionary ** value); 541 542private: 543 virtual void 544 Stop_async( 545 IOService * provider) LOCAL; 546 547 virtual kern_return_t 548 _NewUserClient( 549 uint32_t type, 550 OSDictionary * entitlements, 551 IOUserClient ** userClient) LOCAL; 552}; 553 554#endif /* ! _IOKIT_UIOSERVICE_H */ 555