1*1b191cb5SApple OSS Distributions /* 2*1b191cb5SApple OSS Distributions * Copyright (c) 2000-2019 Apple Inc. All rights reserved. 3*1b191cb5SApple OSS Distributions * 4*1b191cb5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*1b191cb5SApple OSS Distributions * 6*1b191cb5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*1b191cb5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*1b191cb5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*1b191cb5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*1b191cb5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*1b191cb5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*1b191cb5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*1b191cb5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14*1b191cb5SApple OSS Distributions * 15*1b191cb5SApple OSS Distributions * Please obtain a copy of the License at 16*1b191cb5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*1b191cb5SApple OSS Distributions * 18*1b191cb5SApple OSS Distributions * The Original Code and all software distributed under the License are 19*1b191cb5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*1b191cb5SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*1b191cb5SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*1b191cb5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*1b191cb5SApple OSS Distributions * Please see the License for the specific language governing rights and 24*1b191cb5SApple OSS Distributions * limitations under the License. 25*1b191cb5SApple OSS Distributions * 26*1b191cb5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*1b191cb5SApple OSS Distributions */ 28*1b191cb5SApple OSS Distributions 29*1b191cb5SApple OSS Distributions /* 30*1b191cb5SApple OSS Distributions * 31*1b191cb5SApple OSS Distributions * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 32*1b191cb5SApple OSS Distributions * 33*1b191cb5SApple OSS Distributions * HISTORY 34*1b191cb5SApple OSS Distributions * 35*1b191cb5SApple OSS Distributions * 2001-01-17 gvdl Re-implement on IOCommandGate::commandSleep 36*1b191cb5SApple OSS Distributions * 11/13/2000 CJS Created IOCommandPool class and implementation 37*1b191cb5SApple OSS Distributions * 38*1b191cb5SApple OSS Distributions */ 39*1b191cb5SApple OSS Distributions 40*1b191cb5SApple OSS Distributions /*! 41*1b191cb5SApple OSS Distributions * @header IOCommandPool 42*1b191cb5SApple OSS Distributions * @abstract 43*1b191cb5SApple OSS Distributions * This header contains the IOCommandPool class definition. 44*1b191cb5SApple OSS Distributions */ 45*1b191cb5SApple OSS Distributions 46*1b191cb5SApple OSS Distributions #ifndef _IOKIT_IO_COMMAND_POOL_H_ 47*1b191cb5SApple OSS Distributions #define _IOKIT_IO_COMMAND_POOL_H_ 48*1b191cb5SApple OSS Distributions 49*1b191cb5SApple OSS Distributions /* 50*1b191cb5SApple OSS Distributions * Kernel 51*1b191cb5SApple OSS Distributions */ 52*1b191cb5SApple OSS Distributions 53*1b191cb5SApple OSS Distributions #if defined(KERNEL) && defined(__cplusplus) 54*1b191cb5SApple OSS Distributions 55*1b191cb5SApple OSS Distributions #include <kern/kern_types.h> 56*1b191cb5SApple OSS Distributions #include <kern/queue.h> 57*1b191cb5SApple OSS Distributions #include <IOKit/IOCommand.h> 58*1b191cb5SApple OSS Distributions #include <IOKit/IOCommandGate.h> 59*1b191cb5SApple OSS Distributions #include <IOKit/IOService.h> 60*1b191cb5SApple OSS Distributions #include <IOKit/IOWorkLoop.h> 61*1b191cb5SApple OSS Distributions #include <libkern/c++/OSPtr.h> 62*1b191cb5SApple OSS Distributions 63*1b191cb5SApple OSS Distributions /*! 64*1b191cb5SApple OSS Distributions * @class IOCommandPool 65*1b191cb5SApple OSS Distributions * @abstract Manipulates a pool of commands which inherit from IOCommand. 66*1b191cb5SApple OSS Distributions * @discussion 67*1b191cb5SApple OSS Distributions * The IOCommandPool class is used to manipulate a pool of commands which 68*1b191cb5SApple OSS Distributions * inherit from IOCommand. It includes a factory method to create a pool 69*1b191cb5SApple OSS Distributions * of a certain size. Once the factory method is invoked, the semaphore 70*1b191cb5SApple OSS Distributions * is set to zero. The caller must then put commands in the pool by creating 71*1b191cb5SApple OSS Distributions * the command (via the controller's factory method or a memory allocation) 72*1b191cb5SApple OSS Distributions * and calling the returnCommand method with the newly created command as its 73*1b191cb5SApple OSS Distributions * argument. 74*1b191cb5SApple OSS Distributions */ 75*1b191cb5SApple OSS Distributions 76*1b191cb5SApple OSS Distributions class IOCommandPool : public OSObject 77*1b191cb5SApple OSS Distributions { 78*1b191cb5SApple OSS Distributions OSDeclareDefaultStructors(IOCommandPool); 79*1b191cb5SApple OSS Distributions 80*1b191cb5SApple OSS Distributions 81*1b191cb5SApple OSS Distributions protected: 82*1b191cb5SApple OSS Distributions 83*1b191cb5SApple OSS Distributions queue_head_t fQueueHead; /* head of the queue of elements available */ 84*1b191cb5SApple OSS Distributions UInt32 fSleepers; /* Count of threads sleeping on this pool */ 85*1b191cb5SApple OSS Distributions OSPtr<IOCommandGate> fSerializer; /* command gate used for serializing pool access */ 86*1b191cb5SApple OSS Distributions 87*1b191cb5SApple OSS Distributions /*! @struct ExpansionData 88*1b191cb5SApple OSS Distributions * @discussion This structure will be used to expand the capablilties of the IOEventSource in the future. 89*1b191cb5SApple OSS Distributions */ 90*1b191cb5SApple OSS Distributions struct ExpansionData { }; 91*1b191cb5SApple OSS Distributions 92*1b191cb5SApple OSS Distributions /*! @var reserved 93*1b191cb5SApple OSS Distributions * Reserved for future use. (Internal use only) */ 94*1b191cb5SApple OSS Distributions ExpansionData *reserved; 95*1b191cb5SApple OSS Distributions 96*1b191cb5SApple OSS Distributions /*! 97*1b191cb5SApple OSS Distributions * @const kIOCommandPoolDefaultSize 98*1b191cb5SApple OSS Distributions * @abstract The default size of any command pool. 99*1b191cb5SApple OSS Distributions * @discussion 100*1b191cb5SApple OSS Distributions * kIOCommandPoolDefaultSize is the default size of any command pool. 101*1b191cb5SApple OSS Distributions * The default size was determined to be the smallest size for which 102*1b191cb5SApple OSS Distributions * a pool makes sense. 103*1b191cb5SApple OSS Distributions */ 104*1b191cb5SApple OSS Distributions 105*1b191cb5SApple OSS Distributions static const UInt32 kIOCommandPoolDefaultSize = 2; 106*1b191cb5SApple OSS Distributions 107*1b191cb5SApple OSS Distributions /* 108*1b191cb5SApple OSS Distributions * Free all of this object's outstanding resources. 109*1b191cb5SApple OSS Distributions */ 110*1b191cb5SApple OSS Distributions 111*1b191cb5SApple OSS Distributions virtual void free(void) APPLE_KEXT_OVERRIDE; 112*1b191cb5SApple OSS Distributions 113*1b191cb5SApple OSS Distributions 114*1b191cb5SApple OSS Distributions public: 115*1b191cb5SApple OSS Distributions 116*1b191cb5SApple OSS Distributions /*! 117*1b191cb5SApple OSS Distributions * @function initWithWorkLoop 118*1b191cb5SApple OSS Distributions * @abstract Primary initializer for an IOCommandPool object. 119*1b191cb5SApple OSS Distributions * @discussion Primary initializer for an IOCommandPool. 120*1b191cb5SApple OSS Distributions * Should probably use IOCommandPool::withWorkLoop() as it is easier to use. 121*1b191cb5SApple OSS Distributions * @param workLoop 122*1b191cb5SApple OSS Distributions * The workloop that this command pool should synchronize with. 123*1b191cb5SApple OSS Distributions * @result Returns true if command pool was successfully initialized. 124*1b191cb5SApple OSS Distributions */ 125*1b191cb5SApple OSS Distributions virtual bool initWithWorkLoop(IOWorkLoop *workLoop); 126*1b191cb5SApple OSS Distributions 127*1b191cb5SApple OSS Distributions /*! 128*1b191cb5SApple OSS Distributions * @function withWorkLoop 129*1b191cb5SApple OSS Distributions * @abstract Primary factory method for the IOCommandPool class 130*1b191cb5SApple OSS Distributions * @discussion 131*1b191cb5SApple OSS Distributions * The withWorkLoop method is what is known as a factory method. It creates 132*1b191cb5SApple OSS Distributions * a new instance of an IOCommandPool and returns a pointer to that object. 133*1b191cb5SApple OSS Distributions * @param inWorkLoop 134*1b191cb5SApple OSS Distributions * The workloop that this command pool should synchronize with. 135*1b191cb5SApple OSS Distributions * @result 136*1b191cb5SApple OSS Distributions * Returns a pointer to an instance of IOCommandPool if successful, 137*1b191cb5SApple OSS Distributions * otherwise NULL. 138*1b191cb5SApple OSS Distributions */ 139*1b191cb5SApple OSS Distributions 140*1b191cb5SApple OSS Distributions static OSPtr<IOCommandPool> withWorkLoop(IOWorkLoop *inWorkLoop); 141*1b191cb5SApple OSS Distributions 142*1b191cb5SApple OSS Distributions /*! 143*1b191cb5SApple OSS Distributions * @function init 144*1b191cb5SApple OSS Distributions * @abstract Should never be used, obsolete. See initWithWorkLoop. 145*1b191cb5SApple OSS Distributions */ 146*1b191cb5SApple OSS Distributions virtual bool init(IOService *inOwner, 147*1b191cb5SApple OSS Distributions IOWorkLoop *inWorkLoop, 148*1b191cb5SApple OSS Distributions UInt32 inSize = kIOCommandPoolDefaultSize); 149*1b191cb5SApple OSS Distributions 150*1b191cb5SApple OSS Distributions /*! 151*1b191cb5SApple OSS Distributions * @function withWorkLoop 152*1b191cb5SApple OSS Distributions * @abstract Should never be used, obsolete. See IOCommandPool::withWorkLoop. 153*1b191cb5SApple OSS Distributions */ 154*1b191cb5SApple OSS Distributions static OSPtr<IOCommandPool> commandPool(IOService *inOwner, 155*1b191cb5SApple OSS Distributions IOWorkLoop *inWorkLoop, 156*1b191cb5SApple OSS Distributions UInt32 inSize = kIOCommandPoolDefaultSize); 157*1b191cb5SApple OSS Distributions 158*1b191cb5SApple OSS Distributions 159*1b191cb5SApple OSS Distributions /*! 160*1b191cb5SApple OSS Distributions * @function getCommand 161*1b191cb5SApple OSS Distributions * @discussion The getCommand method is used to get a pointer to an object of type IOCommand from the pool. 162*1b191cb5SApple OSS Distributions * @param blockForCommand 163*1b191cb5SApple OSS Distributions * If the caller would like to have its thread slept until a command is 164*1b191cb5SApple OSS Distributions * available, it should pass true, else false. 165*1b191cb5SApple OSS Distributions * @result 166*1b191cb5SApple OSS Distributions * If the caller passes true in blockForCommand, getCommand guarantees that 167*1b191cb5SApple OSS Distributions * the result will be a pointer to an IOCommand object from the pool. If 168*1b191cb5SApple OSS Distributions * the caller passes false, s/he is responsible for checking whether a non-NULL 169*1b191cb5SApple OSS Distributions * pointer was returned. 170*1b191cb5SApple OSS Distributions */ 171*1b191cb5SApple OSS Distributions 172*1b191cb5SApple OSS Distributions virtual OSPtr<IOCommand> getCommand( 173*1b191cb5SApple OSS Distributions bool blockForCommand = true); 174*1b191cb5SApple OSS Distributions 175*1b191cb5SApple OSS Distributions /*! 176*1b191cb5SApple OSS Distributions * @function returnCommand 177*1b191cb5SApple OSS Distributions * @discussion 178*1b191cb5SApple OSS Distributions * The returnCommand method is used to place an object of type IOCommand 179*1b191cb5SApple OSS Distributions * into the pool, whether it be the first time, or the 1000th time. 180*1b191cb5SApple OSS Distributions * @param command 181*1b191cb5SApple OSS Distributions * The command to place in the pool. 182*1b191cb5SApple OSS Distributions */ 183*1b191cb5SApple OSS Distributions 184*1b191cb5SApple OSS Distributions virtual void returnCommand(LIBKERN_CONSUMED IOCommand *command); 185*1b191cb5SApple OSS Distributions 186*1b191cb5SApple OSS Distributions protected: 187*1b191cb5SApple OSS Distributions 188*1b191cb5SApple OSS Distributions /*! 189*1b191cb5SApple OSS Distributions * @function gatedGetCommand 190*1b191cb5SApple OSS Distributions * @discussion 191*1b191cb5SApple OSS Distributions * The gatedGetCommand method is used to serialize the extraction of a 192*1b191cb5SApple OSS Distributions * command from the pool behind a command gate, runAction-ed by getCommand. 193*1b191cb5SApple OSS Distributions * @param command 194*1b191cb5SApple OSS Distributions * A pointer to a pointer to an IOCommand object where the returned 195*1b191cb5SApple OSS Distributions * command will be stored. 196*1b191cb5SApple OSS Distributions * @param blockForCommand 197*1b191cb5SApple OSS Distributions * A bool that indicates whether to block the request until a command 198*1b191cb5SApple OSS Distributions * becomes available. 199*1b191cb5SApple OSS Distributions * @result 200*1b191cb5SApple OSS Distributions * Returns kIOReturnNoResources if no command is available and the client 201*1b191cb5SApple OSS Distributions * doesn't wish to block until one does become available. 202*1b191cb5SApple OSS Distributions * kIOReturnSuccess if the vCommand argument is valid. 203*1b191cb5SApple OSS Distributions */ 204*1b191cb5SApple OSS Distributions virtual IOReturn gatedGetCommand( 205*1b191cb5SApple OSS Distributions LIBKERN_RETURNS_NOT_RETAINED IOCommand **command, bool blockForCommand); 206*1b191cb5SApple OSS Distributions 207*1b191cb5SApple OSS Distributions /*! 208*1b191cb5SApple OSS Distributions * @function gatedReturnCommand 209*1b191cb5SApple OSS Distributions * @discussion 210*1b191cb5SApple OSS Distributions * The gatedReturnCommand method is used to serialize the return of a 211*1b191cb5SApple OSS Distributions * command to the pool behind a command gate, runAction-ed by returnCommand. 212*1b191cb5SApple OSS Distributions * @param command 213*1b191cb5SApple OSS Distributions * A pointer to the IOCommand object to be returned to the pool. 214*1b191cb5SApple OSS Distributions * @result 215*1b191cb5SApple OSS Distributions * Always returns kIOReturnSuccess if the vCommand argument is valid. 216*1b191cb5SApple OSS Distributions */ 217*1b191cb5SApple OSS Distributions virtual IOReturn gatedReturnCommand(IOCommand *command); 218*1b191cb5SApple OSS Distributions 219*1b191cb5SApple OSS Distributions private: 220*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 0); 221*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 1); 222*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 2); 223*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 3); 224*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 4); 225*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 5); 226*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 6); 227*1b191cb5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOCommandPool, 7); 228*1b191cb5SApple OSS Distributions }; 229*1b191cb5SApple OSS Distributions 230*1b191cb5SApple OSS Distributions #endif /* defined(KERNEL) && defined(__cplusplus) */ 231*1b191cb5SApple OSS Distributions 232*1b191cb5SApple OSS Distributions #endif /* _IOKIT_IO_COMMAND_POOL_H_ */ 233