xref: /xnu-10002.61.3/iokit/DriverKit/IOService.iig (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
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