1*0f4c859eSApple OSS Distributions /* 2*0f4c859eSApple OSS Distributions * Copyright (c) 1998-2019 Apple Inc. All rights reserved. 3*0f4c859eSApple OSS Distributions * 4*0f4c859eSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*0f4c859eSApple OSS Distributions * 6*0f4c859eSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*0f4c859eSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*0f4c859eSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*0f4c859eSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*0f4c859eSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*0f4c859eSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*0f4c859eSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*0f4c859eSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*0f4c859eSApple OSS Distributions * 15*0f4c859eSApple OSS Distributions * Please obtain a copy of the License at 16*0f4c859eSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*0f4c859eSApple OSS Distributions * 18*0f4c859eSApple OSS Distributions * The Original Code and all software distributed under the License are 19*0f4c859eSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*0f4c859eSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*0f4c859eSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*0f4c859eSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*0f4c859eSApple OSS Distributions * Please see the License for the specific language governing rights and 24*0f4c859eSApple OSS Distributions * limitations under the License. 25*0f4c859eSApple OSS Distributions * 26*0f4c859eSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*0f4c859eSApple OSS Distributions */ 28*0f4c859eSApple OSS Distributions /* 29*0f4c859eSApple OSS Distributions * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 30*0f4c859eSApple OSS Distributions * HISTORY 31*0f4c859eSApple OSS Distributions * 1998-7-13 Godfrey van der Linden(gvdl) 32*0f4c859eSApple OSS Distributions * Created. 33*0f4c859eSApple OSS Distributions * 1998-10-30 Godfrey van der Linden(gvdl) 34*0f4c859eSApple OSS Distributions * Converted to C++ 35*0f4c859eSApple OSS Distributions */ 36*0f4c859eSApple OSS Distributions #ifndef _IOKIT_IOEVENTSOURCE_H 37*0f4c859eSApple OSS Distributions #define _IOKIT_IOEVENTSOURCE_H 38*0f4c859eSApple OSS Distributions 39*0f4c859eSApple OSS Distributions #include <sys/cdefs.h> 40*0f4c859eSApple OSS Distributions 41*0f4c859eSApple OSS Distributions #include <libkern/c++/OSObject.h> 42*0f4c859eSApple OSS Distributions 43*0f4c859eSApple OSS Distributions #include <IOKit/IOLib.h> 44*0f4c859eSApple OSS Distributions #include <IOKit/system.h> 45*0f4c859eSApple OSS Distributions #include <IOKit/IOWorkLoop.h> 46*0f4c859eSApple OSS Distributions 47*0f4c859eSApple OSS Distributions #if IOKITSTATS 48*0f4c859eSApple OSS Distributions #include <IOKit/IOStatisticsPrivate.h> 49*0f4c859eSApple OSS Distributions #endif 50*0f4c859eSApple OSS Distributions 51*0f4c859eSApple OSS Distributions __BEGIN_DECLS 52*0f4c859eSApple OSS Distributions #include <mach/clock_types.h> 53*0f4c859eSApple OSS Distributions #include <kern/clock.h> 54*0f4c859eSApple OSS Distributions __END_DECLS 55*0f4c859eSApple OSS Distributions 56*0f4c859eSApple OSS Distributions /*! 57*0f4c859eSApple OSS Distributions * @class IOEventSource : public OSObject 58*0f4c859eSApple OSS Distributions * @abstract Abstract class for all work-loop event sources. 59*0f4c859eSApple OSS Distributions * @discussion The IOEventSource declares the abstract super class that all 60*0f4c859eSApple OSS Distributions * event sources must inherit from if an IOWorkLoop is to receive events from them. 61*0f4c859eSApple OSS Distributions * <br><br> 62*0f4c859eSApple OSS Distributions * An event source can represent any event that should cause the work-loop of a 63*0f4c859eSApple OSS Distributions * device to wake up and perform work. Two examples of event sources are the 64*0f4c859eSApple OSS Distributions * IOInterruptEventSource which delivers interrupt notifications and IOCommandGate 65*0f4c859eSApple OSS Distributions * which delivers command requests. 66*0f4c859eSApple OSS Distributions * <br><br> 67*0f4c859eSApple OSS Distributions * A kernel module can always use the work-loop model for serialising access to 68*0f4c859eSApple OSS Distributions * anything at all. The IOEventSource is used for communicating events to the 69*0f4c859eSApple OSS Distributions * work-loop, and the chain of event sources should be used to walk the possible 70*0f4c859eSApple OSS Distributions * event sources and demultipex them. Note a particular instance of an event 71*0f4c859eSApple OSS Distributions * source may only be a member of 1 linked list chain. If you need to move it 72*0f4c859eSApple OSS Distributions * between chains than make sure it is removed from the original chain before 73*0f4c859eSApple OSS Distributions * attempting to move it. 74*0f4c859eSApple OSS Distributions * <br><br> 75*0f4c859eSApple OSS Distributions * The IOEventSource makes no attempt to maintain the consistency of its 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 using an IOCommandGate and thus single threading access to its state. 76*0f4c859eSApple OSS Distributions * <br><br> 77*0f4c859eSApple OSS Distributions * All subclasses of IOEventSource that wish to perform work on the work-loop thread are expected to implement the checkForWork() member function. As of Mac OS X, 10.7 (Darwin 11), checkForWork is no longer pure virtual, and should not be overridden if there is no work to be done. 78*0f4c859eSApple OSS Distributions * 79*0f4c859eSApple OSS Distributions * <br><br> 80*0f4c859eSApple OSS Distributions * checkForWork() is the key method in this class. It is called by some work-loop when convienient and is expected to evaluate its 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. 81*0f4c859eSApple OSS Distributions * <br><br> 82*0f4c859eSApple OSS Distributions * 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. 83*0f4c859eSApple OSS Distributions */ 84*0f4c859eSApple OSS Distributions class IOEventSource : public OSObject 85*0f4c859eSApple OSS Distributions { 86*0f4c859eSApple OSS Distributions OSDeclareAbstractStructors(IOEventSource); 87*0f4c859eSApple OSS Distributions friend class IOWorkLoop; 88*0f4c859eSApple OSS Distributions #if IOKITSTATS 89*0f4c859eSApple OSS Distributions friend class IOStatistics; 90*0f4c859eSApple OSS Distributions #endif 91*0f4c859eSApple OSS Distributions 92*0f4c859eSApple OSS Distributions public: 93*0f4c859eSApple OSS Distributions /*! 94*0f4c859eSApple OSS Distributions * @typedef Action 95*0f4c859eSApple OSS Distributions * @discussion Placeholder type for C++ function overloading discrimination. 96*0f4c859eSApple OSS Distributions * As the all event sources require an action and it has to be stored somewhere 97*0f4c859eSApple OSS Distributions * and be of some type, this is that type. 98*0f4c859eSApple OSS Distributions * @param owner 99*0f4c859eSApple OSS Distributions * Target of the function, can be used as a refcon. The owner is set 100*0f4c859eSApple OSS Distributions * during initialisation. Note if a C++ function was specified this parameter 101*0f4c859eSApple OSS Distributions * is implicitly the first paramter in the target member function's parameter list. 102*0f4c859eSApple OSS Distributions */ 103*0f4c859eSApple OSS Distributions typedef void (*Action)(OSObject *owner, ...); 104*0f4c859eSApple OSS Distributions 105*0f4c859eSApple OSS Distributions /*! @defined IOEventSourceAction 106*0f4c859eSApple OSS Distributions * @discussion Backward compatibilty define for the old non-class scoped type definition. See $link IOEventSource::Action */ 107*0f4c859eSApple OSS Distributions #define IOEventSourceAction IOEventSource::Action 108*0f4c859eSApple OSS Distributions 109*0f4c859eSApple OSS Distributions #ifdef __BLOCKS__ 110*0f4c859eSApple OSS Distributions typedef IOReturn (^ActionBlock)(); 111*0f4c859eSApple OSS Distributions #endif /* __BLOCKS__ */ 112*0f4c859eSApple OSS Distributions 113*0f4c859eSApple OSS Distributions protected: 114*0f4c859eSApple OSS Distributions /*! @var eventChainNext 115*0f4c859eSApple OSS Distributions * The next event source in the event chain. nil at end of chain. */ 116*0f4c859eSApple OSS Distributions IOEventSource *eventChainNext; 117*0f4c859eSApple OSS Distributions 118*0f4c859eSApple OSS Distributions /*! @var owner The owner object called when an event has been delivered. */ 119*0f4c859eSApple OSS Distributions OSObject *owner; 120*0f4c859eSApple OSS Distributions 121*0f4c859eSApple OSS Distributions /*! @var action 122*0f4c859eSApple OSS Distributions * The action method called when an event has been delivered */ 123*0f4c859eSApple OSS Distributions 124*0f4c859eSApple OSS Distributions #if XNU_KERNEL_PRIVATE 125*0f4c859eSApple OSS Distributions union { Action action; ActionBlock actionBlock; }; 126*0f4c859eSApple OSS Distributions #else /* XNU_KERNEL_PRIVATE */ 127*0f4c859eSApple OSS Distributions Action action; 128*0f4c859eSApple OSS Distributions #endif /* !XNU_KERNEL_PRIVATE */ 129*0f4c859eSApple OSS Distributions 130*0f4c859eSApple OSS Distributions /*! @var enabled 131*0f4c859eSApple OSS Distributions * Is this event source enabled to deliver requests to the work-loop. */ 132*0f4c859eSApple OSS Distributions bool enabled; 133*0f4c859eSApple OSS Distributions 134*0f4c859eSApple OSS Distributions #if XNU_KERNEL_PRIVATE 135*0f4c859eSApple OSS Distributions enum{ 136*0f4c859eSApple OSS Distributions kPassive = 0x0001, 137*0f4c859eSApple OSS Distributions kActive = 0x0002, 138*0f4c859eSApple OSS Distributions kActionBlock = 0x0004, 139*0f4c859eSApple OSS Distributions kSubClass0 = 0x0008, 140*0f4c859eSApple OSS Distributions }; 141*0f4c859eSApple OSS Distributions uint8_t eventSourceReserved1[1]; 142*0f4c859eSApple OSS Distributions uint16_t flags; 143*0f4c859eSApple OSS Distributions #if __LP64__ 144*0f4c859eSApple OSS Distributions uint8_t eventSourceReserved2[4]; 145*0f4c859eSApple OSS Distributions #endif /* __LP64__ */ 146*0f4c859eSApple OSS Distributions 147*0f4c859eSApple OSS Distributions #endif /* XNU_KERNEL_PRIVATE */ 148*0f4c859eSApple OSS Distributions 149*0f4c859eSApple OSS Distributions /*! @var workLoop What is the work-loop for this event source. */ 150*0f4c859eSApple OSS Distributions IOWorkLoop *workLoop; 151*0f4c859eSApple OSS Distributions 152*0f4c859eSApple OSS Distributions /*! @var refcon What ever the client wants to do, see $link setRefcon. */ 153*0f4c859eSApple OSS Distributions void *refcon; 154*0f4c859eSApple OSS Distributions 155*0f4c859eSApple OSS Distributions /*! @struct ExpansionData 156*0f4c859eSApple OSS Distributions * @discussion This structure will be used to expand the capablilties of the IOEventSource in the future. 157*0f4c859eSApple OSS Distributions */ 158*0f4c859eSApple OSS Distributions struct ExpansionData { 159*0f4c859eSApple OSS Distributions #if IOKITSTATS 160*0f4c859eSApple OSS Distributions struct IOEventSourceCounter *counter; 161*0f4c859eSApple OSS Distributions #else 162*0f4c859eSApple OSS Distributions void *iokitstatsReserved; 163*0f4c859eSApple OSS Distributions #endif 164*0f4c859eSApple OSS Distributions }; 165*0f4c859eSApple OSS Distributions 166*0f4c859eSApple OSS Distributions /*! @var reserved 167*0f4c859eSApple OSS Distributions * Reserved for future use. (Internal use only) */ 168*0f4c859eSApple OSS Distributions ExpansionData *reserved; 169*0f4c859eSApple OSS Distributions 170*0f4c859eSApple OSS Distributions /*! @function init 171*0f4c859eSApple OSS Distributions * @abstract Primary initialiser for the IOEventSource class. 172*0f4c859eSApple OSS Distributions * @param owner 173*0f4c859eSApple OSS Distributions * Owner of this instance of an event source. Used as the first parameter 174*0f4c859eSApple OSS Distributions * of the action callout. Owner must be an OSObject. 175*0f4c859eSApple OSS Distributions * @param action 176*0f4c859eSApple OSS Distributions * Pointer to C call out function. Action is a pointer to a C function 177*0f4c859eSApple OSS Distributions * that gets called when this event source has outstanding work. It will usually 178*0f4c859eSApple OSS Distributions * be called by the checkForWork member function. The first parameter of the 179*0f4c859eSApple OSS Distributions * action call out will always be the owner, this allows C++ member functions to 180*0f4c859eSApple OSS Distributions * be used as actions. Defaults to 0. 181*0f4c859eSApple OSS Distributions * @result true if the inherited classes and this instance initialise 182*0f4c859eSApple OSS Distributions * successfully. 183*0f4c859eSApple OSS Distributions */ 184*0f4c859eSApple OSS Distributions virtual bool init(OSObject *owner, IOEventSource::Action action = NULL); 185*0f4c859eSApple OSS Distributions 186*0f4c859eSApple OSS Distributions virtual void free( void ) APPLE_KEXT_OVERRIDE; 187*0f4c859eSApple OSS Distributions 188*0f4c859eSApple OSS Distributions /*! @function checkForWork 189*0f4c859eSApple OSS Distributions * @abstract Virtual member function used by IOWorkLoop for work 190*0f4c859eSApple OSS Distributions * scheduling. 191*0f4c859eSApple OSS Distributions * @discussion This function will be called to request a subclass to check 192*0f4c859eSApple OSS Distributions * its internal state for any work to do and then to call out the owner/action. 193*0f4c859eSApple OSS Distributions * If this event source never performs any work (e.g. IOCommandGate), this 194*0f4c859eSApple OSS Distributions * method should not be overridden. NOTE: This method is no longer declared pure 195*0f4c859eSApple OSS Distributions * virtual. A default implementation is provided in IOEventSource. 196*0f4c859eSApple OSS Distributions * @result Return true if this function needs to be called again before all its outstanding events have been processed. 197*0f4c859eSApple OSS Distributions */ 198*0f4c859eSApple OSS Distributions virtual bool checkForWork(); 199*0f4c859eSApple OSS Distributions 200*0f4c859eSApple OSS Distributions /*! @function setWorkLoop 201*0f4c859eSApple OSS Distributions * @abstract Set'ter for $link workLoop variable. 202*0f4c859eSApple OSS Distributions * @param workLoop 203*0f4c859eSApple OSS Distributions * Target work-loop of this event source instance. A subclass of 204*0f4c859eSApple OSS Distributions * IOWorkLoop that at least reacts to signalWorkAvailable() and onThread functions. 205*0f4c859eSApple OSS Distributions */ 206*0f4c859eSApple OSS Distributions virtual void setWorkLoop(IOWorkLoop *workLoop); 207*0f4c859eSApple OSS Distributions 208*0f4c859eSApple OSS Distributions /*! @function setNext 209*0f4c859eSApple OSS Distributions * @abstract Set'ter for $link eventChainNext variable. 210*0f4c859eSApple OSS Distributions * @param next 211*0f4c859eSApple OSS Distributions * Pointer to another IOEventSource instance. 212*0f4c859eSApple OSS Distributions */ 213*0f4c859eSApple OSS Distributions virtual void setNext(IOEventSource *next); 214*0f4c859eSApple OSS Distributions 215*0f4c859eSApple OSS Distributions /*! @function getNext 216*0f4c859eSApple OSS Distributions * @abstract Get'ter for $link eventChainNext variable. 217*0f4c859eSApple OSS Distributions * @result value of eventChainNext. 218*0f4c859eSApple OSS Distributions */ 219*0f4c859eSApple OSS Distributions virtual IOEventSource *getNext() const; 220*0f4c859eSApple OSS Distributions 221*0f4c859eSApple OSS Distributions 222*0f4c859eSApple OSS Distributions protected: 223*0f4c859eSApple OSS Distributions // Methods to access the IOWorkLoop exported fields 224*0f4c859eSApple OSS Distributions void signalWorkAvailable(); 225*0f4c859eSApple OSS Distributions void openGate(); 226*0f4c859eSApple OSS Distributions void closeGate(); 227*0f4c859eSApple OSS Distributions bool tryCloseGate(); 228*0f4c859eSApple OSS Distributions int sleepGate(void *event, UInt32 type); 229*0f4c859eSApple OSS Distributions int sleepGate(void *event, AbsoluteTime deadline, UInt32 type); 230*0f4c859eSApple OSS Distributions void wakeupGate(void *event, bool oneThread); 231*0f4c859eSApple OSS Distributions 232*0f4c859eSApple OSS Distributions public: 233*0f4c859eSApple OSS Distributions /*! @function setAction 234*0f4c859eSApple OSS Distributions * @abstract Set'ter for $link action variable. 235*0f4c859eSApple OSS Distributions * @param action Pointer to a C function of type IOEventSource::Action. */ 236*0f4c859eSApple OSS Distributions virtual void setAction(IOEventSource::Action action); 237*0f4c859eSApple OSS Distributions 238*0f4c859eSApple OSS Distributions /*! @function getAction 239*0f4c859eSApple OSS Distributions * @abstract Get'ter for $link action variable. 240*0f4c859eSApple OSS Distributions * @result value of action. */ 241*0f4c859eSApple OSS Distributions virtual IOEventSource::Action getAction() const; 242*0f4c859eSApple OSS Distributions 243*0f4c859eSApple OSS Distributions #ifdef __BLOCKS__ 244*0f4c859eSApple OSS Distributions /*! @function setActionBlock 245*0f4c859eSApple OSS Distributions * @abstract Setter for action ivar. The current block is released, & the new block is retained. 246*0f4c859eSApple OSS Distributions * @param block Block pointer of type IOEventSource::ActionBlock. */ 247*0f4c859eSApple OSS Distributions void setActionBlock(ActionBlock block); 248*0f4c859eSApple OSS Distributions /*! @function getActionBlock 249*0f4c859eSApple OSS Distributions * @abstract Getter for action ivar. 250*0f4c859eSApple OSS Distributions * @result Block pointer of type IOEventSource::ActionBlock, if set, or NULL. */ 251*0f4c859eSApple OSS Distributions ActionBlock getActionBlock(ActionBlock) const; 252*0f4c859eSApple OSS Distributions #endif /* __BLOCKS__ */ 253*0f4c859eSApple OSS Distributions 254*0f4c859eSApple OSS Distributions /*! @function setRefcon 255*0f4c859eSApple OSS Distributions * @abstract Setter for refcon ivar. This function will assert if a block action has been set. 256*0f4c859eSApple OSS Distributions * @param refcon Refcon. */ 257*0f4c859eSApple OSS Distributions void setRefcon(void *refcon); 258*0f4c859eSApple OSS Distributions /*! @function getRefcon 259*0f4c859eSApple OSS Distributions * @abstract Getter for refcon ivar. 260*0f4c859eSApple OSS Distributions * @result The refcon. This function will assert if a block action has been set. */ 261*0f4c859eSApple OSS Distributions void * getRefcon() const; 262*0f4c859eSApple OSS Distributions 263*0f4c859eSApple OSS Distributions /*! @function enable 264*0f4c859eSApple OSS Distributions * @abstract Enable event source. 265*0f4c859eSApple OSS Distributions * @discussion A subclass implementation is expected to respect the enabled 266*0f4c859eSApple OSS Distributions * state when checkForWork is called. Calling this function will cause the 267*0f4c859eSApple OSS Distributions * work-loop to be signalled so that a checkForWork is performed. */ 268*0f4c859eSApple OSS Distributions virtual void enable(); 269*0f4c859eSApple OSS Distributions 270*0f4c859eSApple OSS Distributions /*! @function disable 271*0f4c859eSApple OSS Distributions * @abstract Disable event source. 272*0f4c859eSApple OSS Distributions * @discussion A subclass implementation is expected to respect the enabled 273*0f4c859eSApple OSS Distributions * state when checkForWork is called. */ 274*0f4c859eSApple OSS Distributions virtual void disable(); 275*0f4c859eSApple OSS Distributions 276*0f4c859eSApple OSS Distributions /*! @function isEnabled 277*0f4c859eSApple OSS Distributions * @abstract Get'ter for $link enable variable. 278*0f4c859eSApple OSS Distributions * @result true if enabled. */ 279*0f4c859eSApple OSS Distributions virtual bool isEnabled() const; 280*0f4c859eSApple OSS Distributions 281*0f4c859eSApple OSS Distributions /*! @function getWorkLoop 282*0f4c859eSApple OSS Distributions * @abstract Get'ter for $link workLoop variable. 283*0f4c859eSApple OSS Distributions * @result value of workLoop. */ 284*0f4c859eSApple OSS Distributions virtual IOWorkLoop *getWorkLoop() const; 285*0f4c859eSApple OSS Distributions 286*0f4c859eSApple OSS Distributions /*! @function onThread 287*0f4c859eSApple OSS Distributions * @abstract Convenience function for workLoop->onThread. 288*0f4c859eSApple OSS Distributions * @result true if called on the work-loop thread. 289*0f4c859eSApple OSS Distributions */ 290*0f4c859eSApple OSS Distributions virtual bool onThread() const; 291*0f4c859eSApple OSS Distributions 292*0f4c859eSApple OSS Distributions private: 293*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 0); 294*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 1); 295*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 2); 296*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 3); 297*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 4); 298*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 5); 299*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 6); 300*0f4c859eSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOEventSource, 7); 301*0f4c859eSApple OSS Distributions }; 302*0f4c859eSApple OSS Distributions 303*0f4c859eSApple OSS Distributions #endif /* !_IOKIT_IOEVENTSOURCE_H */ 304