1/*
2 * Copyright (c) 1998-2011 Apple 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#ifndef _IOMBUFQUEUE_H
24#define _IOMBUFQUEUE_H
25
26extern "C" {
27#include <sys/param.h>
28#include <sys/mbuf.h>
29}
30
31struct IOMbufQueue
32{
33    mbuf_t      head;
34    mbuf_t      tail;
35    uint32_t    count;
36    uint32_t    capacity;
37    uint32_t    bytes;
38};
39
40static __inline__
41int IOMbufFree(mbuf_t m)
42{
43	return mbuf_freem_list(m);
44}
45
46static __inline__
47void IOMbufQueueInit( IOMbufQueue * q, uint32_t capacity = 0 )
48{
49    q->head  = q->tail = 0;
50    q->count = 0;
51    q->bytes = 0;
52    q->capacity = capacity;
53}
54
55static __inline__
56bool IOMbufQueueEnqueue( IOMbufQueue * q, mbuf_t m )
57{
58    if (q->count >= q->capacity)
59        return false;
60
61    if (q->count++ > 0)
62        mbuf_setnextpkt(q->tail , m);
63    else
64        q->head = m;
65
66    for (q->tail = m;
67         mbuf_nextpkt(q->tail);
68         q->tail = mbuf_nextpkt(q->tail), q->count++)
69        ;
70
71    return true;
72}
73
74static __inline__
75bool IOMbufQueueEnqueue( IOMbufQueue * q, IOMbufQueue * qe )
76{
77    if (qe->count)
78    {
79        if (q->count == 0)
80            q->head = qe->head;
81        else
82            mbuf_setnextpkt(q->tail , qe->head);
83        q->tail = qe->tail;
84        q->count += qe->count;
85
86        qe->head = qe->tail = 0;
87        qe->count = 0;
88    }
89    return true;
90}
91
92static __inline__
93void IOMbufQueuePrepend( IOMbufQueue * q, mbuf_t m )
94{
95    mbuf_t tail;
96
97    for (tail = m, q->count++;
98         mbuf_nextpkt(tail);
99         tail = mbuf_nextpkt(tail), q->count++)
100        ;
101
102    mbuf_setnextpkt(tail , q->head);
103    if (q->tail == 0)
104        q->tail = tail;
105    q->head = m;
106}
107
108static __inline__
109void IOMbufQueuePrepend( IOMbufQueue * q, IOMbufQueue * qp )
110{
111    if (qp->count)
112    {
113        mbuf_setnextpkt(qp->tail , q->head);
114        if (q->tail == 0)
115            q->tail = qp->tail;
116        q->head = qp->head;
117        q->count += qp->count;
118
119        qp->head = qp->tail = 0;
120        qp->count = 0;
121    }
122}
123
124static __inline__
125mbuf_t IOMbufQueueDequeue( IOMbufQueue * q )
126{
127    mbuf_t m = q->head;
128    if (m)
129    {
130        if ((q->head = mbuf_nextpkt(m)) == 0)
131            q->tail = 0;
132        mbuf_setnextpkt(m , 0);
133        q->count--;
134    }
135    return m;
136}
137
138static __inline__
139mbuf_t IOMbufQueueDequeueAll( IOMbufQueue * q )
140{
141    mbuf_t m = q->head;
142    q->head = q->tail = 0;
143    q->count = 0;
144    return m;
145}
146
147static __inline__
148mbuf_t IOMbufQueuePeek( IOMbufQueue * q )
149{
150    return q->head;
151}
152
153static __inline__
154uint32_t IOMbufQueueGetSize( IOMbufQueue * q )
155{
156    return q->count;
157}
158
159static __inline__
160uint32_t IOMbufQueueIsEmpty( IOMbufQueue * q )
161{
162    return (0 == q->count);
163}
164
165static __inline__
166uint32_t IOMbufQueueGetCapacity( IOMbufQueue * q )
167{
168    return q->capacity;
169}
170
171static __inline__
172void IOMbufQueueSetCapacity( IOMbufQueue * q, uint32_t capacity )
173{
174	q->capacity = capacity;
175}
176
177static __inline__
178void IOMbufQueueTailAdd( IOMbufQueue * q, mbuf_t m, uint32_t len )
179{
180    if (q->count == 0)
181    {
182        q->head = q->tail = m;
183    }
184    else
185    {
186        mbuf_setnextpkt(q->tail, m);
187        q->tail = m;
188    }
189    q->count++;
190    q->bytes += len;
191}
192
193#endif /* !_IOMBUFQUEUE_H */
194