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/*
29Copyright (c) 1998 Apple Computer, Inc.	 All rights reserved.
30HISTORY
31    1998-7-13	Godfrey van der Linden(gvdl)
32	Created.
33    1998-10-30	Godfrey van der Linden(gvdl)
34	Converted to C++
35*/
36#ifndef _IOKIT_IOEVENTSOURCE_H
37#define _IOKIT_IOEVENTSOURCE_H
38
39#include <sys/cdefs.h>
40
41#include <libkern/c++/OSObject.h>
42
43#include <IOKit/IOLib.h>
44#include <IOKit/system.h>
45#include <IOKit/IOWorkLoop.h>
46
47
48__BEGIN_DECLS
49#include <mach/clock_types.h>
50#include <kern/clock.h>
51__END_DECLS
52
53/*!
54    @class IOEventSource : public OSObject
55    @abstract Abstract class for all work-loop event sources.
56    @discussion The IOEventSource declares the abstract super class that all
57event sources must inherit from if an IOWorkLoop is to receive events from them.
58<br><br>
59	An event source can represent any event that should cause the work-loop of a
60device to wake up and perform work.  Two examples of event sources are the
61IOInterruptEventSource which delivers interrupt notifications and IOCommandGate
62which delivers command requests.
63<br><br>
64	A kernel module can always use the work-loop model for serialising access to
65anything at all.  The IOEventSource is used for communicating events to the
66work-loop, and the chain of event sources should be used to walk the possible
67event sources and demultipex them.  Note a particular instance of an event
68source may only be a member of 1 linked list chain.  If you need to move it
69between chains than make sure it is removed from the original chain before
70attempting to move it.
71<br><br>
72	The IOEventSource makes no attempt to maintain the consitency of it's internal data across multi-threading.  It is assumed that the user of these basic tools will protect the data that these objects represent in some sort of device wide instance lock.	For example the IOWorkLoop maintains the event chain by handing off change request to its own thread and thus single threading access to its state.
73<br><br>
74	All subclasses of the IOEventSource are expected to implement the checkForWork() member function.
75
76<br><br>
77	checkForWork() is the key method in this class.	 It is called by some work-loop when convienient and is expected to evaluate it's internal state and determine if an event has occurred since the last call.  In the case of an event having occurred then the instance defined target(owner)/action will be called.	 The action is stored as an ordinary C function pointer but the first parameter is always the owner.  This means that a C++ member function can be used as an action function though this depends on the ABI.
78<br><br>
79	Although the eventChainNext variable contains a reference to the next event source in the chain this reference is not retained.  The list 'owner' i.e. the client that creates the event, not the work-loop, is expected to retain the source.
80*/
81class IOEventSource : public OSObject
82{
83    OSDeclareAbstractStructors(IOEventSource)
84    friend class IOWorkLoop;
85
86public:
87/*!
88    @typedef Action
89    @discussion Placeholder type for C++ function overloading discrimination.
90As the all event sources require an action and it has to be stored somewhere
91and be of some type, this is that type.
92    @param owner
93	Target of the function, can be used as a refcon.  The owner is set
94during initialisation.	 Note if a C++ function was specified this parameter
95is implicitly the first paramter in the target member function's parameter list.
96*/
97    typedef void (*Action)(OSObject *owner, ...);
98
99/*! @defined IOEventSourceAction
100    @discussion Backward compatibilty define for the old non-class scoped type definition.  See $link IOEventSource::Action */
101 #define IOEventSourceAction IOEventSource::Action
102
103protected:
104/*! @var eventChainNext
105	The next event source in the event chain. nil at end of chain. */
106    IOEventSource *eventChainNext;
107
108/*! @var owner The owner object called when an event has been delivered. */
109    OSObject *owner;
110
111/*! @var action
112	The action method called when an event has been delivered */
113    Action action;
114
115/*! @var enabled
116	Is this event source enabled to deliver requests to the work-loop. */
117    bool enabled;
118
119/*! @var workLoop What is the work-loop for this event source. */
120    IOWorkLoop *workLoop;
121
122/*! @var refcon What ever the client wants to do, see $link setRefcon. */
123    void *refcon;
124
125/*! @struct ExpansionData
126    @discussion This structure will be used to expand the capablilties of the IOEventSource in the future.
127    */
128    struct ExpansionData { };
129
130/*! @var reserved
131    Reserved for future use.  (Internal use only)  */
132    ExpansionData *reserved;
133
134/*! @function init
135    @abstract Primary initialiser for the IOEventSource class.
136    @param owner
137	Owner of this instance of an event source.  Used as the first parameter
138of the action callout.	Owner will generally be an OSObject it doesn't have to
139be as no member functions will be called directly in it.  It can just be a
140refcon for a client routine.
141    @param action
142	Pointer to C call out function.	 Action is a pointer to a C function
143that gets called when this event source has outstanding work.  It will usually
144be called by the checkForWork member function.	The first parameter of the
145action call out will always be the owner, this allows C++ member functions to
146be used as actions.  Defaults to 0.
147    @result true if the inherited classes and this instance initialise
148successfully.
149*/
150    virtual bool init(OSObject *owner, IOEventSource::Action action = 0);
151
152/*! @function checkForWork
153    @abstract Pure Virtual member function used by IOWorkLoop for work
154scheduling.
155    @discussion This function will be called to request a subclass to check
156it's internal state for any work to do and then to call out the owner/action.
157    @result Return true if this function needs to be called again before all its outstanding events have been processed.
158        */
159    virtual bool checkForWork() = 0;
160
161/*! @function setWorkLoop
162    @abstract Set'ter for $link workLoop variable.
163    @param workLoop
164	Target work-loop of this event source instance.	 A subclass of
165IOWorkLoop that at least reacts to signalWorkAvailable() and onThread functions.
166*/
167    virtual void setWorkLoop(IOWorkLoop *workLoop);
168
169/*! @function setNext
170    @abstract Set'ter for $link eventChainNext variable.
171    @param next
172	Pointer to another IOEventSource instance.
173*/
174    virtual void setNext(IOEventSource *next);
175
176/*! @function getNext
177    @abstract Get'ter for $link eventChainNext variable.
178    @result value of eventChainNext.
179*/
180    virtual IOEventSource *getNext() const;
181
182
183protected:
184    // Methods to access the IOWorkLoop exported fields
185    /* inline */ void signalWorkAvailable();
186        /* { workLoop->signalWorkAvailable(); }; */
187    /* inline */ void openGate();
188        /* { workLoop->openGate(); }; */
189    /* inline */ void closeGate();
190        /* { workLoop->closeGate(); }; */
191    /* inline */ bool tryCloseGate();
192        /* { return workLoop->tryCloseGate(); }; */
193    /* inline */ int sleepGate(void *event, UInt32 type);
194        /* { return workLoop->sleepGate(event, type); }; */
195    /* inline */ void wakeupGate(void *event, bool oneThread);
196        /* { workLoop->wakeupGate(event, oneThread); }; */
197
198public:
199/*! @function setAction
200    @abstract Set'ter for $link action variable.
201    @param action Pointer to a C function of type IOEventSource::Action. */
202    virtual void setAction(IOEventSource::Action action);
203
204/*! @function getAction
205    @abstract Get'ter for $link action variable.
206    @result value of action. */
207    virtual IOEventSource::Action getAction() const;
208
209/*! @function enable
210    @abstract Enable event source.
211    @discussion A subclass implementation is expected to respect the enabled
212state when checkForWork is called.  Calling this function will cause the
213work-loop to be signalled so that a checkForWork is performed. */
214    virtual void enable();
215
216/*! @function disable
217    @abstract Disable event source.
218    @discussion A subclass implementation is expected to respect the enabled
219state when checkForWork is called. */
220    virtual void disable();
221
222/*! @function isEnabled
223    @abstract Get'ter for $link enable variable.
224    @result true if enabled. */
225    virtual bool isEnabled() const;
226
227/*! @function getWorkLoop
228    @abstract Get'ter for $link workLoop variable.
229    @result value of workLoop. */
230    virtual IOWorkLoop *getWorkLoop() const;
231
232/*! @function onThread
233    @abstract Convenience function for workLoop->onThread.
234    @result true if called on the work-loop thread.
235*/
236    virtual bool onThread() const;
237
238private:
239    OSMetaClassDeclareReservedUnused(IOEventSource, 0);
240    OSMetaClassDeclareReservedUnused(IOEventSource, 1);
241    OSMetaClassDeclareReservedUnused(IOEventSource, 2);
242    OSMetaClassDeclareReservedUnused(IOEventSource, 3);
243    OSMetaClassDeclareReservedUnused(IOEventSource, 4);
244    OSMetaClassDeclareReservedUnused(IOEventSource, 5);
245    OSMetaClassDeclareReservedUnused(IOEventSource, 6);
246    OSMetaClassDeclareReservedUnused(IOEventSource, 7);
247};
248
249#endif /* !_IOKIT_IOEVENTSOURCE_H */
250