]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/network/IOBasicOutputQueue.h
aa3f83c2dccdc48171f14cb48aa0674abe8289ae
[apple/xnu.git] / iokit / IOKit / network / IOBasicOutputQueue.h
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * IOBasicOutputQueue.h
26 *
27 * HISTORY
28 *
29 */
30
31 #ifndef _IOBASICOUTPUTQUEUE_H
32 #define _IOBASICOUTPUTQUEUE_H
33
34 #include <IOKit/IOLocks.h>
35 #include <IOKit/network/IOOutputQueue.h>
36 #include <IOKit/network/IOPacketQueue.h> // FIXME - remove
37
38 struct IOMbufQueue;
39
40 /*! @class IOBasicOutputQueue : public IOOutputQueue
41 @abstract A concrete implementation of an IOOutputQueue. This object
42 uses a spinlock to protect the packet queue from multiple producers.
43 A single producer is promoted to become a consumer when the queue is
44 not active. Otherwise, the producer will simply queue the packet and
45 return without blocking.
46
47 The flow of packets from the queue to its target can be controlled
48 by calling methods such as start(), stop(), or service(). The target
49 is expected to call those methods from a single threaded context,
50 i.e. the work loop context in a network driver. In addition, the
51 target must also return a status for every packet delivered by the
52 consumer thread. This return value is the only mechanism that the
53 target can use to manage the queue when it is running on the
54 consumer thread. */
55
56 class IOBasicOutputQueue : public IOOutputQueue
57 {
58 OSDeclareDefaultStructors( IOBasicOutputQueue )
59
60 private:
61 static IOReturn dispatchNetworkDataNotification(void * target,
62 void * param,
63 IONetworkData * data,
64 UInt32 type);
65
66 void dequeue();
67
68 protected:
69 OSObject * _target;
70 IOOutputAction _action;
71 IOOutputQueueStats * _stats;
72 IONetworkData * _statsData;
73 IOSimpleLock * _spinlock;
74 IOMbufQueue * _inQueue;
75 IOMbufQueue * _queues[2];
76 volatile bool _waitDequeueDone;
77 volatile UInt32 _state;
78 volatile UInt32 _serviceCount;
79
80 /*! @function serviceThread
81 @abstract Method called by the scheduled service thread when it
82 starts to run.
83 @discussion Provide an implementation for the serviceThread() method
84 defined in IOOutputQueue. The service thread is scheduled by service()
85 to restart a stalled queue when the kServiceAsync options is given.
86 @param A parameter that was given to scheduleServiceThread().
87 This parameter is not used. */
88
89 virtual void serviceThread(void * param);
90
91 /*! @function output
92 @abstract Transfer all packets in the mbuf queue to the target.
93 @param queue A queue of output packets.
94 @param state Return a state bit defined by IOBasicOutputQueue that
95 declares the new state of the queue following this method call.
96 A kStateStalled is returned if the queue should stall, otherwise 0
97 is returned. */
98
99 virtual void output(IOMbufQueue * queue, UInt32 * state);
100
101 /*! @function free
102 @abstract Free the IOBasicOutputQueue object.
103 @discussion Release allocated resources, then call super::free(). */
104
105 virtual void free();
106
107 /*! @function handleNetworkDataAccess
108 @abstract Handle an external access to the IONetworkData object
109 returned by getStatisticsData().
110 @param data The IONetworkData object being accessed.
111 @param type Describes the type of access being performed.
112 @param param An optional parameter for the handler.
113 @result kIOReturnSuccess on success, or an error code otherwise. */
114
115 virtual IOReturn handleNetworkDataAccess(IONetworkData * data,
116 UInt32 type,
117 void * param);
118
119 public:
120
121 /*! @function init
122 @abstract Initialize an IOBasicOutputQueue object.
123 @param target The object that will handle packets removed from the
124 queue, and is usually a subclass of IONetworkController.
125 @param action The function that will handle packets removed from the
126 queue.
127 @param capacity The initial capacity of the output queue.
128 @result true if initialized successfully, false otherwise. */
129
130 virtual bool init(OSObject * target,
131 IOOutputAction action,
132 UInt32 capacity = 0);
133
134 /*! @function withTarget
135 @abstract Factory method that will construct and initialize an
136 IOBasicOutputQueue object.
137 @param target An IONetworkController object that will handle packets
138 removed from the queue.
139 @param capacity The initial capacity of the output queue.
140 @result An IOBasicOutputQueue object on success, or 0 otherwise. */
141
142 static IOBasicOutputQueue * withTarget(IONetworkController * target,
143 UInt32 capacity = 0);
144
145 /*! @function withTarget
146 @abstract Factory method that will construct and initialize an
147 IOBasicOutputQueue object.
148 @param target The object that will handle packets removed from the
149 queue.
150 @param action The function that will handle packets removed from the
151 queue.
152 @param capacity The initial capacity of the output queue.
153 @result An IOBasicOutputQueue object on success, or 0 otherwise. */
154
155 static IOBasicOutputQueue * withTarget(OSObject * target,
156 IOOutputAction action,
157 UInt32 capacity = 0);
158
159 /*! @function enqueue
160 @abstract Called by a client to add a packet, or a chain of packets,
161 to the queue.
162 @discussion A packet is described by a mbuf chain, while a chain
163 of packets is constructed by linking multiple mbuf chains via the
164 m_nextpkt field. This method can be called by multiple client
165 threads.
166 @param m A single packet, or a chain of packets.
167 @param param A parameter provided by the caller.
168 @result Always return 0. */
169
170 virtual UInt32 enqueue(struct mbuf * m, void * param);
171
172 /*! @function start
173 @abstract Start up the packet flow between the queue and its target.
174 @discussion Called by the target to start the queue. This will allow
175 packets to be removed from the queue, and then delivered to the target.
176 @result true if the queue was started successfully, false otherwise. */
177
178 virtual bool start();
179
180 /*! @function stop
181 @abstract Stop the packet flow between the queue and its target.
182 @discussion Stop the queue and prevent it from sending packets to its
183 target. This call is synchronous and it may block. After this method
184 returns, the queue will no longer call the registered target/action,
185 even as new packets are added to the queue. The queue will continue to
186 absorb new packets until the size of the queue reaches its capacity.
187 The registered action must never call stop(), or a deadlock will occur.
188 @result Returns the previous running state of the queue,
189 true if the queue was running, false if the queue was already stopped. */
190
191 virtual bool stop();
192
193 /*! @enum An enumeration of the option bits recognized by service().
194 @constant kServiceAsync Set this option to service the queue in
195 an asynchronous manner. The service() call will not block, but a
196 scheduling latency will be introduced before the queue is serviced. */
197
198 enum {
199 kServiceAsync = 0x1
200 };
201
202 /*! @function service
203 @abstract Service a queue that was stalled by the target.
204 @discussion A target that stalls the queue must call service() when
205 it becomes ready to accept more packets. Calling this methods when the
206 queue is not stalled is harmless.
207 @result true if the queue was stalled and there were packets sitting in
208 the queue awaiting delivery, false otherwise. */
209
210 virtual bool service(IOOptionBits options = 0);
211
212 /*! @function flush
213 @abstract Drop and free all packets currently held by the queue.
214 @discussion To ensure that all packets are removed from the queue,
215 stop() should be called prior to flush(), to make sure there are
216 no packets in-flight and being delivered to the target.
217 @result The number of packets that were dropped and freed. */
218
219 virtual UInt32 flush();
220
221 /*! @function setCapacity
222 @abstract Change the number of packets that the queue can hold
223 before it begins to drop excess packets.
224 @param capacity The new desired capacity.
225 @result true if the new capacity was accepted, false otherwise. */
226
227 virtual bool setCapacity(UInt32 capacity);
228
229 /*! @function getCapacity
230 @abstract Get the number of packets that the queue can hold.
231 @discussion The queue will begin to drop incoming packets when the
232 size of queue reaches its capacity.
233 @result The current queue capacity. */
234
235 virtual UInt32 getCapacity() const;
236
237 /*! @function getSize
238 @abstract Get the number of packets currently held in the queue.
239 @result The size of the queue. */
240
241 virtual UInt32 getSize() const;
242
243 /*! @function getDropCount
244 @abstract Get the number of packets dropped by the queue.
245 @result The number of packets dropped due to over-capacity, or by
246 external calls to the flush() method. */
247
248 virtual UInt32 getDropCount();
249
250 /*! @function getOutputCount
251 @sbstract Get the number of packets accepted by the target.
252 @result The number of times that kIOOutputStatusAccepted is returned by
253 the target. */
254
255 virtual UInt32 getOutputCount();
256
257 /*! @function getRetryCount
258 @abstract Get the number of instances when the target has refused to
259 accept the packet provided.
260 @result The number of times that kIOOutputStatusRetry is returned by the
261 target. */
262
263 virtual UInt32 getRetryCount();
264
265 /*! @function getStallCount
266 @abstract Get the number of instances when the target has stalled the
267 queue.
268 @result The number of times that kIOOutputCommandStall is returned by the
269 target. */
270
271 virtual UInt32 getStallCount();
272
273 /*! @enum An enumeration of the bits in the value returned by getState().
274 @constant kStateRunning Set when the queue is running. Calling start()
275 and stop() will set or clear this bit.
276 @constant kStateStalled Set when the queue is stalled by the target.
277 @constant kStateActive Set when a consumer thread is actively removing
278 packets from the queue and passing them to the target. */
279
280 enum {
281 kStateRunning = 0x1,
282 kStateOutputStalled = 0x2,
283 kStateOutputActive = 0x4,
284 kStateOutputServiceMask = 0xff00
285 };
286
287 /*! @function getState
288 @abstract Get the state of the queue object.
289 @result The current state of the queue object. */
290
291 virtual UInt32 getState() const;
292
293 /*! @function getStatisticsData
294 @abstract Return an IONetworkData object containing statistics counters
295 updated by the queue.
296 @result An IONetworkData object. */
297
298 virtual IONetworkData * getStatisticsData() const;
299 };
300
301 #endif /* !_IOBASICOUTPUTQUEUE_H */