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