1/*
2 * Copyright (c) 1998-2000 Apple Computer, 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/*
30 * Changes to this API are expected.
31 */
32
33#ifndef _IOKIT_IOUSERCLIENT_H
34#define _IOKIT_IOUSERCLIENT_H
35
36#include <IOKit/IOTypes.h>
37#include <IOKit/IOService.h>
38#include <IOKit/OSMessageNotification.h>
39
40#if IOKITSTATS
41#include <IOKit/IOStatisticsPrivate.h>
42#endif
43
44enum {
45    kIOUCTypeMask	= 0x0000000f,
46    kIOUCScalarIScalarO = 0,
47    kIOUCScalarIStructO = 2,
48    kIOUCStructIStructO = 3,
49    kIOUCScalarIStructI = 4,
50
51    kIOUCForegroundOnly = 0x00000010,
52};
53
54/*! @enum
55    @abstract Constant to denote a variable length structure argument to IOUserClient.
56    @constant kIOUCVariableStructureSize Use in the structures IOExternalMethod, IOExternalAsyncMethod, IOExternalMethodDispatch to specify the size of the structure is variable.
57*/
58enum {
59    kIOUCVariableStructureSize = 0xffffffff
60};
61
62
63typedef IOReturn (IOService::*IOMethod)(void * p1, void * p2, void * p3,
64                                        void * p4, void * p5, void * p6 );
65
66typedef IOReturn (IOService::*IOAsyncMethod)(OSAsyncReference asyncRef,
67                                        void * p1, void * p2, void * p3,
68                                        void * p4, void * p5, void * p6 );
69
70typedef IOReturn (IOService::*IOTrap)(void * p1, void * p2, void * p3,
71                                      void * p4, void * p5, void * p6 );
72
73struct IOExternalMethod {
74    IOService *		object;
75    IOMethod		func;
76    IOOptionBits	flags;
77    IOByteCount		count0;
78    IOByteCount		count1;
79};
80
81struct IOExternalAsyncMethod {
82    IOService *		object;
83    IOAsyncMethod	func;
84    IOOptionBits	flags;
85    IOByteCount		count0;
86    IOByteCount		count1;
87};
88
89struct IOExternalTrap {
90    IOService *		object;
91    IOTrap		func;
92};
93
94enum {
95    kIOUserNotifyMaxMessageSize = 64
96};
97
98// keys for clientHasPrivilege
99#define kIOClientPrivilegeAdministrator	"root"
100#define kIOClientPrivilegeLocalUser	"local"
101#define kIOClientPrivilegeForeground	"foreground"
102
103/*! @enum
104    @abstract Constants to specify the maximum number of scalar arguments in the IOExternalMethodArguments structure. These constants are documentary since the scalarInputCount, scalarOutputCount fields reflect the actual number passed.
105    @constant kIOExternalMethodScalarInputCountMax The maximum number of scalars able to passed on input.
106    @constant kIOExternalMethodScalarOutputCountMax The maximum number of scalars able to passed on output.
107*/
108enum {
109    kIOExternalMethodScalarInputCountMax  = 16,
110    kIOExternalMethodScalarOutputCountMax = 16,
111};
112
113
114struct IOExternalMethodArguments
115{
116    uint32_t		version;
117
118    uint32_t		selector;
119
120    mach_port_t           asyncWakePort;
121    io_user_reference_t * asyncReference;
122    uint32_t              asyncReferenceCount;
123
124    const uint64_t *    scalarInput;
125    uint32_t		scalarInputCount;
126
127    const void *	structureInput;
128    uint32_t		structureInputSize;
129
130    IOMemoryDescriptor * structureInputDescriptor;
131
132    uint64_t *		scalarOutput;
133    uint32_t		scalarOutputCount;
134
135    void *		structureOutput;
136    uint32_t		structureOutputSize;
137
138    IOMemoryDescriptor * structureOutputDescriptor;
139    uint32_t		 structureOutputDescriptorSize;
140
141    uint32_t		__reservedA;
142
143    OSObject **         structureVariableOutputData;
144
145    uint32_t		__reserved[30];
146};
147
148typedef IOReturn (*IOExternalMethodAction)(OSObject * target, void * reference,
149					    IOExternalMethodArguments * arguments);
150struct IOExternalMethodDispatch
151{
152    IOExternalMethodAction function;
153    uint32_t		   checkScalarInputCount;
154    uint32_t		   checkStructureInputSize;
155    uint32_t		   checkScalarOutputCount;
156    uint32_t		   checkStructureOutputSize;
157};
158
159enum {
160#define IO_EXTERNAL_METHOD_ARGUMENTS_CURRENT_VERSION	2
161    kIOExternalMethodArgumentsCurrentVersion = IO_EXTERNAL_METHOD_ARGUMENTS_CURRENT_VERSION
162};
163
164
165/*!
166    @class IOUserClient
167    @abstract   Provides a basis for communication between client applications and I/O Kit objects.
168*/
169
170
171class IOUserClient : public IOService
172{
173    OSDeclareAbstractStructors(IOUserClient)
174#if IOKITSTATS
175    friend class IOStatistics;
176#endif
177
178protected:
179/*! @struct ExpansionData
180    @discussion This structure will be used to expand the capablilties of this class in the future.
181*/
182    struct ExpansionData {
183#if IOKITSTATS
184	    IOUserClientCounter *counter;
185#else
186	    void *iokitstatsReserved;
187#endif
188    };
189
190/*! @var reserved
191    Reserved for future use.  (Internal use only)
192*/
193    ExpansionData * reserved;
194
195    bool reserve();
196
197#ifdef XNU_KERNEL_PRIVATE
198public:
199#else
200private:
201#endif
202    OSSet * mappings;
203    UInt8   sharedInstance;
204    UInt8   __reservedA[3];
205    void  * __reserved[7];
206
207public:
208   virtual IOReturn externalMethod( uint32_t selector, IOExternalMethodArguments * arguments,
209					IOExternalMethodDispatch * dispatch = 0, OSObject * target = 0, void * reference = 0 );
210
211   virtual IOReturn registerNotificationPort(
212					mach_port_t port, UInt32 type, io_user_reference_t refCon);
213
214private:
215#if __LP64__
216    OSMetaClassDeclareReservedUnused(IOUserClient, 0);
217    OSMetaClassDeclareReservedUnused(IOUserClient, 1);
218#else
219    OSMetaClassDeclareReservedUsed(IOUserClient, 0);
220    OSMetaClassDeclareReservedUsed(IOUserClient, 1);
221#endif
222    OSMetaClassDeclareReservedUnused(IOUserClient, 2);
223    OSMetaClassDeclareReservedUnused(IOUserClient, 3);
224    OSMetaClassDeclareReservedUnused(IOUserClient, 4);
225    OSMetaClassDeclareReservedUnused(IOUserClient, 5);
226    OSMetaClassDeclareReservedUnused(IOUserClient, 6);
227    OSMetaClassDeclareReservedUnused(IOUserClient, 7);
228    OSMetaClassDeclareReservedUnused(IOUserClient, 8);
229    OSMetaClassDeclareReservedUnused(IOUserClient, 9);
230    OSMetaClassDeclareReservedUnused(IOUserClient, 10);
231    OSMetaClassDeclareReservedUnused(IOUserClient, 11);
232    OSMetaClassDeclareReservedUnused(IOUserClient, 12);
233    OSMetaClassDeclareReservedUnused(IOUserClient, 13);
234    OSMetaClassDeclareReservedUnused(IOUserClient, 14);
235    OSMetaClassDeclareReservedUnused(IOUserClient, 15);
236
237#ifdef XNU_KERNEL_PRIVATE
238    /* Available within xnu source only */
239public:
240    static void initialize( void );
241    static void destroyUserReferences( OSObject * obj );
242    IOMemoryMap * mapClientMemory64( IOOptionBits type,
243                                    task_t task,
244                                    IOOptionBits mapFlags = kIOMapAnywhere,
245				    mach_vm_address_t atAddress = 0 );
246#endif
247
248protected:
249    static IOReturn sendAsyncResult(OSAsyncReference reference,
250                                    IOReturn result, void *args[], UInt32 numArgs);
251    static void setAsyncReference(OSAsyncReference asyncRef,
252                                  mach_port_t wakePort,
253                                  void *callback, void *refcon);
254
255    static IOReturn sendAsyncResult64(OSAsyncReference64 reference,
256                                        IOReturn result, io_user_reference_t args[], UInt32 numArgs);
257    static void setAsyncReference64(OSAsyncReference64 asyncRef,
258					mach_port_t wakePort,
259					mach_vm_address_t callback, io_user_reference_t refcon);
260public:
261
262    static IOReturn clientHasPrivilege( void * securityToken,
263                                        const char * privilegeName );
264
265    /*!
266        @function releaseAsyncReference64
267	@abstract Release the mach_port_t reference held within the OSAsyncReference64 structure.
268	@discussion The OSAsyncReference64 structure passed to async methods holds a reference to the wakeup mach port, which should be released to balance each async method call. Behavior is undefined if these calls are not correctly balanced.
269        @param reference The reference passed to the subclass IOAsyncMethod, or externalMethod() in the IOExternalMethodArguments.asyncReference field.
270        @result A return code.
271    */
272    static IOReturn releaseAsyncReference64(OSAsyncReference64 reference);
273    /*!
274        @function releaseNotificationPort
275	@abstract Release the mach_port_t passed to registerNotificationPort().
276	@discussion The mach_port_t passed to the registerNotificationPort() methods should be released to balance each call to registerNotificationPort(). Behavior is undefined if these calls are not correctly balanced.
277        @param reference The mach_port_t argument previously passed to the subclass implementation of registerNotificationPort().
278        @result A return code.
279    */
280    static IOReturn releaseNotificationPort(mach_port_t port);
281
282    virtual bool init();
283    virtual bool init( OSDictionary * dictionary );
284    // Currently ignores the all args, just passes up to IOService::init()
285    virtual bool initWithTask(
286                    task_t owningTask, void * securityToken, UInt32 type,
287                    OSDictionary * properties);
288
289    virtual bool initWithTask(
290                    task_t owningTask, void * securityToken, UInt32 type);
291
292    virtual void free();
293
294    virtual IOReturn clientClose( void );
295    virtual IOReturn clientDied( void );
296
297    virtual IOService * getService( void );
298
299    virtual IOReturn registerNotificationPort(
300		mach_port_t port, UInt32 type, UInt32 refCon );
301
302    virtual IOReturn getNotificationSemaphore( UInt32 notification_type,
303                                    semaphore_t * semaphore );
304
305    virtual IOReturn connectClient( IOUserClient * client );
306
307    // memory will be released by user client when last map is destroyed
308    virtual IOReturn clientMemoryForType( UInt32 type,
309			        IOOptionBits * options,
310				IOMemoryDescriptor ** memory );
311
312#if !__LP64__
313private:
314	APPLE_KEXT_COMPATIBILITY_VIRTUAL
315	IOMemoryMap * mapClientMemory( IOOptionBits type,
316                                    task_t task,
317                                    IOOptionBits mapFlags = kIOMapAnywhere,
318									IOVirtualAddress atAddress = 0 );
319#endif
320
321public:
322
323    /*!
324        @function removeMappingForDescriptor
325        Remove the first mapping created from the memory descriptor returned by clientMemoryForType() from IOUserClient's list of mappings. If such a mapping exists, it is retained and the reference currently held by IOUserClient is returned to the caller.
326        @param memory The memory descriptor instance previously returned by the implementation of clientMemoryForType().
327        @result A reference to the first IOMemoryMap instance found in the list of mappings created by IOUserClient from that passed memory descriptor is returned, or zero if none exist. The caller should release this reference.
328    */
329    IOMemoryMap * removeMappingForDescriptor(IOMemoryDescriptor * memory);
330
331    /*!
332        @function exportObjectToClient
333        Make an arbitrary OSObject available to the client task.
334        @param task The task.
335        @param obj The object we want to export to the client.
336        @param clientObj Returned value is the client's port name.
337    */
338    virtual IOReturn exportObjectToClient(task_t task,
339				OSObject *obj, io_object_t *clientObj);
340
341    // Old methods for accessing method vector backward compatiblility only
342    virtual IOExternalMethod *
343        getExternalMethodForIndex( UInt32 index )
344	APPLE_KEXT_DEPRECATED;
345    virtual IOExternalAsyncMethod *
346        getExternalAsyncMethodForIndex( UInt32 index )
347	APPLE_KEXT_DEPRECATED;
348
349    // Methods for accessing method vector.
350    virtual IOExternalMethod *
351        getTargetAndMethodForIndex( IOService ** targetP, UInt32 index );
352    virtual IOExternalAsyncMethod *
353        getAsyncTargetAndMethodForIndex( IOService ** targetP, UInt32 index );
354
355    // Methods for accessing trap vector - old and new style
356    virtual IOExternalTrap *
357		getExternalTrapForIndex( UInt32 index )
358	APPLE_KEXT_DEPRECATED;
359
360    virtual IOExternalTrap *
361      getTargetAndTrapForIndex( IOService **targetP, UInt32 index );
362};
363
364#endif /* ! _IOKIT_IOUSERCLIENT_H */
365
366