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