1/*
2 * Copyright (c) 1998-2010 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#ifndef _IOKIT_IOAUDIOCONTROL_H
24#define _IOKIT_IOAUDIOCONTROL_H
25
26#include <IOKit/IOService.h>
27#ifndef IOAUDIOFAMILY_SELF_BUILD
28#include <IOKit/audio/IOAudioEngine.h>
29#else
30#include "IOAudioEngine.h"
31#endif
32
33class IOAudioPort;
34class OSDictionary;
35class OSSet;
36class IOAudioUserClient;
37class IOAudioControlUserClient;
38class IOWorkLoop;
39class IOCommandGate;
40
41/*!
42 * @class IOAudioControl
43 * @abstract Represents any controllable attribute of an IOAudioDevice.
44 * @discussion An IOAudioControl instance may belong to one IOAudioPort.  Additionally, it may associated
45 *  with an IOAudioEngine as a default control for that IOAudioEngine.
46 *
47 *  When its value changes, it sends a notification to the CoreAudio.framework (HAL).  It also makes a call
48 *  to the ValueChangeHandler.
49 *
50 *  The base IOAudioControl class contains a type, a value and a channel ID representing the channel(s) which
51 *  the control acts on.  It may also contain a readable format for the name of the channel as well as a
52 *  control ID that can be used to identify unique controls.  Additionally it may contain a subType and a usage.
53 *  Each type has its own set of possible subTypes.  There currently four different control types defined:
54 *  kIOAudioControlTypeLevel, kIOAudioControlTypeToggle, kIOAudioControlTypeSelector.
55 *  Each one is represented by a subclass of IOAudioControl: IOAudioLevelControl, IOAudioToggleControl,
56 *  IOAudioSelectorControl.  The level control defines a range of allowed values and has
57 *  a defined subtype of kIOAudioLevelControlSubTypeVolume used to define a volume control.  The toggle control
58 *  allows for a boolean value and has a defined subtype kIOAudioToggleControlSubTypeMute for a mute control.  The
59 *  selector control has a list of allowed selections with a value and description for each allowed selection and
60 *  has the following sub types: kIOAudioSelectorControlSubTypeOutput for an output selector and
61 *  kIOAudioSelectorControlSubTypeInput for an input selector.  See the subclass documentation for a more
62 *  complete description of each
63 *
64 *  There are enums for default channel ID values and common channel names in IOAudioTypes.h.  The channel ID
65 *  values are prefixed with 'kIOAudioControlChannelID' and the common channel names are prefixed with
66 *  'kIOAudioControlChannelName'.  All of the attributes of the IOAudioControl are stored in the registry.
67 *  The key used for each attribute is defined in IOAudioTypes.h with the define matching the following
68 *  pattern: 'kIOAudioControl<attribute name>Key'.  For example: kIOAudioControlChannelIDKey.
69 *
70 *  In addition to the existing defined control types, drivers can define their own as well for other purposes.
71 *
72 *  Changes to the IOAudioControl's value made by the CoreAudio.framework are done through the IORegistry.
73 *  When the CoreAudio.framework initiates a value change, the control receives a setProperties() message.
74 *  The setProperties() implementation looks for the property 'IOAudioControlValue' and if present, calls
75 *  setValue() on the driver's IOWorkLoop with the new value.  The setValue() function first checks to see
76 *  if the new value is different.  If so, it calls performValueChange() to call through to the driver
77 *  to make the change in the hardware.  If that call succeeds the value is changed and the new value is set
78 *  in the registry.  Additionally notifications are sent to all clients that have registered for them.
79 */
80class IOAudioControl : public IOService
81{
82    friend class IOAudioPort;
83    friend class IOAudioDevice;
84    friend class IOAudioEngine;
85
86    OSDeclareDefaultStructors(IOAudioControl)
87
88public:
89
90    /*!
91     * @typedef IntValueChangeHandler
92     * @abstract Handler function used to make a notification when a value is to be changed.
93     * @param target Reference supplied when the handler was registered.
94     * @param audioControl The IOAudioControl that is changing.
95	 * @param oldValue The old value of the control.
96     * @param newValue The new value the control is being changed to.
97	 * @result Must return kIOReturnSuccess when the hardware is successfully updated.
98     */
99    typedef IOReturn (*IntValueChangeHandler)(OSObject *target, IOAudioControl *audioControl, SInt32 oldValue, SInt32 newValue);
100    typedef IOReturn (*DataValueChangeHandler)(OSObject *target, IOAudioControl *audioControl, const void *oldData, UInt32 oldDataSize, const void *newData, UInt32 newDataSize);
101    typedef IOReturn (*ObjectValueChangeHandler)(OSObject *target, IOAudioControl *audioControl, OSObject *oldValue, OSObject *newValue);
102
103protected:
104    /*! @var workLoop
105        The IOWorkLoop for the audio driver - shared from the IOAudioDevice.
106    */
107    IOWorkLoop 		*workLoop;
108    /*! @var commandGate
109        The IOCommandGate for this control - attached to the driver's IOWorkLoop.
110    */
111    IOCommandGate	*commandGate;
112
113    /*! @var isStarted
114        Internal state keeping track of when the IOAudioControl has been started.
115    */
116    bool		isStarted;
117
118    /*! @var controlID
119        An optional identifier that can be used to identify the control.
120    */
121    UInt32 		controlID;
122    /*! @var channelID
123        The ID of the channel this control affects - may be kIOAudioControlChannelIDAll if it represents all channels.
124    */
125    UInt32		channelID;
126
127    UInt32		type;
128    UInt32		subType;
129    UInt32		usage;
130
131    OSObject	*value;
132
133    typedef enum {
134        kIntValueChangeHandler,
135        kDataValueChangeHandler,
136        kObjectValueChangeHandler
137    } ValueChangeHandlerType;
138
139    ValueChangeHandlerType valueChangeHandlerType;
140
141    union {
142        IntValueChangeHandler		intHandler;
143        DataValueChangeHandler		dataHandler;
144        ObjectValueChangeHandler	objectHandler;
145    } valueChangeHandler;
146
147    OSObject	*valueChangeTarget;
148
149    /*! @var clients
150        A list of user clients that have requested value change notifications.
151    */
152    OSSet		*userClients;
153
154protected:
155    struct ExpansionData {
156		IOAudioEngine *				providerEngine;
157		OSArray *					notificationQueue;
158		UInt32						commandGateStatus;			// <rdar://8518215>
159		SInt32						commandGateUsage;			// <rdar://8518215>
160	};
161
162    ExpansionData *reserved;
163
164public:
165	// OSMetaClassDeclareReservedUsed(IOAudioControl, 0);
166	virtual void sendChangeNotification(UInt32 notificationType);
167
168	// OSMetaClassDeclareReservedUsed(IOAudioControl, 1);
169    /*!
170	 * @function setReadOnlyFlag
171     * @abstract Call this function to say that a control is read only.
172	 * This call cannot be undone, so if a control is only temporarily unsetable,
173	 * do not use this call but instead return an error from the control handler.
174     */
175	virtual void setReadOnlyFlag();
176
177	// OSMetaClassDeclareReservedUsed(IOAudioControl, 2);
178	virtual void sendQueuedNotifications(void);
179
180	// OSMetaClassDeclareReservedUsed(IOAudioControl, 3);
181    /*!
182     * @function createUserClient
183     * @abstract Creates a new IOAudioControlUserClient instance.
184     * @discussion This function is called by newUserClient() to create a new IOAudioControlUserClient instance.  This function may be overridden by subclasses that need to add functionality
185     *  to the IOAudioControlUserClient.  In that case, they must subclass IOAudioControlUserClient
186     *  and return a new, initialized instance of that subclass.
187	 *  A derived class that requires overriding of createUserClient should override the version with the properties
188	 *  parameter for Intel targets, and without the properties parameter for PPC targets.  The #if __i386__ directive
189	 *  can be used to select between the two behaviors.
190     * @param task The task requesting the new user client.
191     * @param securityID Optional security paramater passed in by the client - ignored.
192     * @param type Optional user client type passed in by the client.
193     * @param newUserClient The IOAudioControlUserClient * must be stored in this param on a successful
194     *  completion.
195     * @param properties A dictionary of additional properties for the connection.
196     * @result Returns kIOReturnSuccess on success.
197     */
198    virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioControlUserClient **newUserClient, OSDictionary *properties);
199
200private:
201    OSMetaClassDeclareReservedUsed(IOAudioControl, 0);
202    OSMetaClassDeclareReservedUsed(IOAudioControl, 1);
203    OSMetaClassDeclareReservedUsed(IOAudioControl, 2);
204    OSMetaClassDeclareReservedUsed(IOAudioControl, 3);
205
206    OSMetaClassDeclareReservedUnused(IOAudioControl, 4);
207    OSMetaClassDeclareReservedUnused(IOAudioControl, 5);
208    OSMetaClassDeclareReservedUnused(IOAudioControl, 6);
209    OSMetaClassDeclareReservedUnused(IOAudioControl, 7);
210    OSMetaClassDeclareReservedUnused(IOAudioControl, 8);
211    OSMetaClassDeclareReservedUnused(IOAudioControl, 9);
212    OSMetaClassDeclareReservedUnused(IOAudioControl, 10);
213    OSMetaClassDeclareReservedUnused(IOAudioControl, 11);
214    OSMetaClassDeclareReservedUnused(IOAudioControl, 12);
215    OSMetaClassDeclareReservedUnused(IOAudioControl, 13);
216    OSMetaClassDeclareReservedUnused(IOAudioControl, 14);
217    OSMetaClassDeclareReservedUnused(IOAudioControl, 15);
218    OSMetaClassDeclareReservedUnused(IOAudioControl, 16);
219    OSMetaClassDeclareReservedUnused(IOAudioControl, 17);
220    OSMetaClassDeclareReservedUnused(IOAudioControl, 18);
221    OSMetaClassDeclareReservedUnused(IOAudioControl, 19);
222    OSMetaClassDeclareReservedUnused(IOAudioControl, 20);
223    OSMetaClassDeclareReservedUnused(IOAudioControl, 21);
224    OSMetaClassDeclareReservedUnused(IOAudioControl, 22);
225    OSMetaClassDeclareReservedUnused(IOAudioControl, 23);
226
227public:
228
229    /*!
230     * @function withAttributes
231     * @abstract Static function that allocates a new IOAudioControl with the given attributes.
232     * @param type The type of the control.  Common, known types are defined in IOAudioTypes.h.  They currently
233     *  consist of kIOAudioControlTypeLevel, kIOAudioControlTypeToggle, kIOAudioControlTypeSelector.
234     * @param channelID The ID of the channel(s) that the control acts on.  Common IDs are located in IOAudioTypes.h.
235     * @param channelName An optional name for the channel.  Common names are located in IOAudioDefines.h.  Any name not
236     *  defined in IOAudioDefines.h must be localized in order to be properly displayed in multiple languages.
237     * @param cntrlID An optional ID for the control that can be used to uniquely identify controls
238     * @param subType An optional subType specific to the given type
239     * @param usage An optional value specifying how the control will be used.  Currently defined usages are kIOAudioControlUsageInput,
240     *  kIOAudioControlUsageOutput and kIOAudioControlUsagePassThru.  This value is used when a control is set as a default control
241     *  on an IOAudioEngine.
242     * @result Returns a newly allocated and initialized IOAudioControl.
243     */
244    static IOAudioControl *withAttributes(UInt32 type,
245                                          OSObject *initialValue,
246                                          UInt32 channelID,
247                                          const char *channelName = 0,
248                                          UInt32 cntrlID = 0,
249                                          UInt32 subType = 0,
250                                          UInt32 usage = 0);
251
252    /*!
253     * @function init
254     * @abstract Initializes a newly allocated IOAudioControl with the given attributes.
255     * @param type The type of the control.  Common, known types are defined in IOAudioTypes.h.  They currently
256     *  consist of kIOAudioControlTypeLevel, kIOAudioControlTypeToggle, kIOAudioControlTypeSelector.
257     * @param channelID The ID of the channel(s) that the control acts on.  Common IDs are located in IOAudioTypes.h.
258     * @param channelName An optional name for the channel.  Common names are located in IOAudioDefines.h.  Any name not
259     *  defined in IOAudioDefines.h must be localized in order to be properly displayed in multiple languages.
260     * @param cntrlID An optional ID for the control that can be used to uniquely identify controls
261     * @param subType An optional subType specific to the given type
262     * @param usage An optional value specifying how the control will be used.  Currently defined usages are kIOAudioControlUsageInput,
263     *  kIOAudioControlUsageOutput and kIOAudioControlUsagePassThru.  This value is used when a control is set as a default control
264     *  on an IOAudioEngine.
265     * @param properties Standard property list passed to the init() function of any new IOService.  This dictionary
266     *  gets stored in the registry entry for this instance.
267     * @result Returns true on success.
268     */
269    virtual bool init(UInt32 type,
270                      OSObject *initialValue,
271                      UInt32 channelID,
272                      const char *channelName = 0,
273                      UInt32 cntrlID = 0,
274                      UInt32 subType = 0,
275                      UInt32 usage = 0,
276                      OSDictionary *properties = 0);
277
278    /*!
279     * @function free
280     * @abstract Frees all of the resources allocated by the IOAudioControl.
281     * @discussion Do not call this directly.  This is called automatically by the system when the instance's
282     *  refcount goes to 0.  To decrement the refcount, call release() on the object.
283     */
284    virtual void free();
285
286    /*!
287     * @function start
288     * @abstract Starts a newly created IOAudioControl.
289     * @discussion This is called automatically by IOAudioPort when addAudioControl() is called or by IOAudioEngine
290     *  when addDefaultAudioControl() is called.  It will only be called by the first call to either addAudioControl() or
291     *  addDefaultAudioControl().
292     * @param provider The IOAudioPort or IOAudioEngine that owns this control.
293     * @result Returns true on success.
294     */
295    virtual bool start(IOService *provider);
296
297	virtual bool attachAndStart(IOService *provider);
298
299    /*!
300     * @function getIsStarted
301     * @abstract Returns true after start() has been called.
302     * @discussion Used by IOAudioPort and IOAudioEngine to decide if the control needs to be started.
303     */
304    virtual bool getIsStarted();
305
306    /*!
307     * @function stop
308     * @abstract Stops the control when the provider is going away.
309     * @param provider The IOAudioPort or IOAudioEngine that owns this control.
310     */
311    virtual void stop(IOService *provider);
312
313    /*!
314     * @function getWorkLoop
315     * @abstract Returns the IOWorkLoop for the whole audio driver.
316     */
317    virtual IOWorkLoop *getWorkLoop();
318
319    /*!
320     * @function getCommandGate
321     * @abstract Returns the IOCommandGate for this IOAudioControl.
322     */
323    virtual IOCommandGate *getCommandGate();
324
325    /*!
326     * @function newUserClient
327     * @abstract Creates a new user client object for this IOAudioControl instance.
328     * @discussion This is called automatically by I/O Kit when a user process opens a connection to this
329     *  IOAudioControl.  This is typically done when the user process needs to register for value change
330     *  notifications.  This implementation allocates a new IOAudioControlUserClient object.  There is no
331     *  need to call this directly.
332	 *  A derived class that requires overriding of newUserClient should override the version with the properties
333	 *  parameter for Intel targets, and without the properties parameter for PPC targets.  The #if __i386__ directive
334	 *  can be used to select between the two behaviors.
335     * @param task The task requesting the new user client.
336     * @param securityID Optional security paramater passed in by the client - ignored.
337     * @param type Optional user client type passed in by the client - 0 for the default user client type.
338     * @param handler The new IOUserClient * must be stored in this param on a successful completion.
339     * @param properties A dictionary of additional properties for the connection.
340     * @result Returns kIOReturnSuccess on success.  May also result kIOReturnError or kIOReturnNoMemory.
341     */
342    virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, IOUserClient **handler);
343    virtual IOReturn newUserClient(task_t task, void *securityID, UInt32 type, OSDictionary *properties, IOUserClient **handler);
344
345    /*!
346     * @function createUserClient
347     * @abstract Creates a new IOAudioControlUserClient instance.
348     * @discussion This function is called by newUserClient() to create a new IOAudioControlUserClient instance.  This function may be overridden by subclasses that need to add functionality
349     *  to the IOAudioControlUserClient.  In that case, they must subclass IOAudioControlUserClient
350     *  and return a new, initialized instance of that subclass.
351	 *  A derived class that requires overriding of createUserClient should override the version with the properties
352	 *  parameter for Intel targets, and without the properties parameter for PPC targets.  The #if __i386__ directive
353	 *  can be used to select between the two behaviors.
354     * @param task The task requesting the new user client.
355     * @param securityID Optional security paramater passed in by the client - ignored.
356     * @param type Optional user client type passed in by the client.
357     * @param newUserClient The IOAudioControlUserClient * must be stored in this param on a successful
358     *  completion.
359     * @result Returns kIOReturnSuccess on success.
360     */
361    virtual IOReturn createUserClient(task_t task, void *securityID, UInt32 type, IOAudioControlUserClient **newUserClient);
362
363    /*!
364     * @function clientClosed
365     * @abstract Called automatically by the IOAudioControlUserClient when a user client closes its
366     *  connection to the control.
367     * @param client The user client object that has disconnected.
368     */
369    virtual void clientClosed(IOAudioControlUserClient *client);
370
371    /*!
372     * @function setProperties
373     * @abstract Changes a property of this IOService.
374     * @discussion This is called when the user client changes a property of this
375     *  IOAudioControl.  In this case it is used to change the value.  This function
376     *  looks for that property and then calls setValue() through the IOCommandGate and
377     *  setValueAction().
378     * @param properties An OSDictionary containing the properties to change.
379     * @result Returns kIOReturnSuccess on success.
380     */
381    virtual IOReturn setProperties(OSObject *properties);
382
383    virtual void setValueChangeHandler(IntValueChangeHandler intValueChangeHandler, OSObject *target);
384    virtual void setValueChangeHandler(DataValueChangeHandler dataValueChangeHandler, OSObject *target);
385    virtual void setValueChangeHandler(ObjectValueChangeHandler objectValueChangeHandler, OSObject *target);
386
387    virtual void setValueChangeTarget(OSObject *target);
388
389    /*!
390     * @function flushValue
391     * @abstract Forces the control to be flushed out to the hardware.
392     * @discussion This function calls performValueChange() directly with the current value of the IOAudioControl.
393     * @result Returns the result of performValueChange() - kIOReturnSuccess on success.
394     */
395    virtual IOReturn flushValue();
396
397    /*!
398     * @function setValueAction
399     * @abstract IOCommandGate Action which calls setValue() while holding the IOCommandGate.
400     * @discussion This is needed to allow setValue() to be called on the IOWorkLoop.
401     * @param owner The owner of the IOCommandGate (the IOAudioControl in this case).
402     * @param arg1 The new value for the IOAudioControl.
403     * @result Returns the result of setValue() - kIOReturnSuccess on success.
404     */
405    static IOReturn setValueAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
406
407	static IOReturn _setValueAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);	// <rdar://7529580>
408
409    /*!
410     * @function setValue
411     * @abstract Sets the value for this control.
412     * @discussion When the control's value is changed, a call is made to performValueChange().  If that call
413     *  succeeds, the value is set and sendValueChangeNotification() is called to send a notification to the
414     *  user clients.  This function must be called on the IOWorkLoop.
415     * @param newValue The new value for this control.
416     * @result Returns kIOReturnSuccess if the value is successfully set.
417     */
418    virtual IOReturn setValue(OSObject *newValue);
419
420    virtual IOReturn setValue(SInt32 intValue);
421
422    /*!
423     * @function hardwareValueChanged
424     * @abstract Updates the value for this control and sends out the value changed notification.
425     * @discussion This is designed to be called by the driver when it detects that the hardware's value has
426     *  changed without driver intervention (e.g. when an external event causes the change).  The difference between
427     *  hardwareValueChanged() and setValue() is that hardwareValueChanged() doesn't call performValueChange() which
428     *  sends a message back to the driver to cause it to change the hardware with the new value.  This function must
429     *  be called on the IOWorkLoop.
430     * @param newValue The new value for this control.
431     * @result Returns kIOReturnSuccess if the value is successfully updated.
432     */
433    virtual IOReturn hardwareValueChanged(OSObject *newValue);
434
435    /*!
436     * @function getValue
437     * @abstract Returns the current value of the control.
438     */
439    virtual OSObject *getValue();
440    virtual SInt32 getIntValue();
441    virtual const void *getDataBytes();
442    virtual UInt32 getDataLength();
443
444    /*!
445     * @function getControlID
446     * @abstract Returns the control ID for the control.
447     */
448    virtual UInt32 getControlID();
449
450    /*!
451     * @function getChannelID
452     * @abstract Returns the channel ID for the control.
453     */
454    virtual UInt32 getChannelID();
455
456    virtual UInt32 getType();
457    virtual UInt32 getSubType();
458    virtual UInt32 getUsage();
459
460    virtual void setCoreAudioPropertyID(UInt32 propertyID);
461
462	void setWorkLoop(IOWorkLoop *wl);
463
464protected:
465    /*!
466     * @function sendValueChangeNotification
467     * @abstract Called when the value has changed for the control.
468     * @discussion This function sends out the value change notification to the user clients.
469     */
470    virtual void sendValueChangeNotification();
471
472    /*!
473     * @function setChannelName
474     * @abstract Called at init time to set the channel name for this IOAudioControl.
475     */
476    virtual void setChannelName(const char *channelName);
477
478    /*!
479     * @function setChannelID
480     * @abstract Called at init time to set the channel ID for this IOAudioControl.
481     */
482    virtual void setChannelID(UInt32 newChannelID);
483    virtual void setChannelNumber(SInt32 channelNumber);
484
485    /*!
486     * @function setSubType
487     * @abstract Called at init time to set the control subType.
488     */
489    virtual void setType(UInt32 type);
490
491    /*!
492     * @function setType
493     * @abstract Called at init time to set the control type.
494     */
495    virtual void setSubType(UInt32 subType);
496
497    /*!
498     * @function setUsage
499     * @abstract Called at init time to set the control usage.
500     */
501    virtual void setUsage(UInt32 usage);
502
503    /*!
504     * @function setControlID
505     * @abstract Sets the controlID for this control.
506     * @discussion The control ID is an optional attribute that can be used to track IOAudioControls.  A typical
507     *  use is for the IOAudioDevice to assign a unique controlID to each control that it creates and then
508     *  do a switch statement on the id of the control when it gets an audioControlValueChanged() notification.
509     *  Typically the control ID is set when the object is created and doesn't need to be called again.
510     * @param cntrlID The control ID for the control.
511     */
512    virtual void setControlID(UInt32 cntrlID);
513
514    /*!
515     * @function validateValue
516     * @abstract Called by setValue() to verify that the value is valid.
517     * @param newValue The new value to be verified.
518     * @result Returns kIOReturnSuccess if the value is valid.
519     */
520    virtual IOReturn validateValue(OSObject *newValue);
521
522    /*!
523     * @function updateValue
524     * @abstract Called by setValue() in order to update the value and the registry.
525     * @discussion It also calls
526     *  sendValueChangedNotification() to send notifications to the user clients.
527     * @param newValue The new value to b updated.
528     * @result Returns kIOReturnSuccess if the value is successfully updated.
529     */
530    virtual IOReturn updateValue(OSObject *newValue);
531
532    virtual IOReturn _setValue(OSObject *newValue);
533
534    /*!
535     * @function performValueChange
536     * @abstract Called by setValue() to make the call to the valueChangeHandler
537     *  to update the hardware.
538     * @result Returns the result of the handler call (or kIOReturnError on an error).
539     */
540    virtual IOReturn performValueChange(OSObject *newValue);
541
542    /*!
543     * @function addUserClientAction
544     * @abstract IOCommandGate Action which calls addUserClient() while holding the IOCommandGate.
545     * @discussion This is needed to allow addUserClient() to be called on the IOWorkLoop.
546     * @param owner The owner of the IOCommandGate (the IOAudioControl in this case).
547     * @param arg1 The IOAudioControlUserClient to be added.
548     * @result Returns the result of addUserClient() - kIOReturnSuccess on success.
549     */
550    static IOReturn addUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
551
552	static IOReturn _addUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);	// <rdar://7529580>
553
554    /*!
555     * @function removeUserClientAction
556     * @abstract IOCommandGate Action which calls removeUserClient() while holding the IOCommandGate.
557     * @discussion This is needed to allow removeUserClient() to be called on the IOWorkLoop.
558     * @param owner The owner of the IOCommandGate (the IOAudioControl in this case).
559     * @param arg1 The IOAudioControlUserClient to be removed.
560     * @result Returns the result of removeUserClient() - kIOReturnSuccess on success.
561     */
562    static IOReturn removeUserClientAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
563
564	static IOReturn _removeUserClientAction(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3);	// <rdar://7529580>
565
566    /*!
567     * @function detachUserClientsAction
568     */
569     static IOReturn detachUserClientsAction(OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4);
570
571    /*!
572     * @function addUserClient
573     * @abstract Called on the IOWorkLoop to add a new IOAudioControlUserClient.
574     * @discussion There is no need to call this directly.  It is called on the workLoop
575     *  by newUserClient() through addUserClientAction().
576     * @param newUserClient The IOAudioControlUserClientto be added.
577     * @result Returns kIOReturnSuccess on success.
578     */
579    virtual IOReturn addUserClient(IOAudioControlUserClient *newUserClient);
580
581    /*!
582     * @function removeUserClient
583     * @abstract Called on the IOWorkLoop to remove an IOAudioControlUserClient.
584     * @discussion This is called on the IOWorkLoop by clientClosed() through
585     *  removeUserClientAction() when the user client is going away.  It should
586     *  not be called directly.
587     * @param userClient The IOAudioControlUserClient to be removed.
588     * @result Returns kIOReturnSuccess on success.
589     */
590    virtual IOReturn removeUserClient(IOAudioControlUserClient *userClient);
591
592    virtual IOReturn detachUserClients();
593
594	static void setCommandGateUsage(IOAudioControl *control, bool increment);		// <rdar://8518215>
595
596};
597
598#endif /* _IOKIT_IOAUDIOCONTROL_H */
599
600