xref: /xnu-8796.141.3/iokit/IOKit/IOCommandPool.h (revision 1b191cb58250d0705d8a51287127505aa4bc0789)
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