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