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