]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/bcm570x_queue.h
2 /******************************************************************************/
4 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 Broadcom */
6 /* All rights reserved. */
8 /* This program is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU General Public License as published by */
10 /* the Free Software Foundation, located in the file LICENSE. */
12 /* Queue functions. */
13 /* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
14 /* char QQ_Full(PQQ_CONTAINER pQueue) */
15 /* char QQ_Empty(PQQ_CONTAINER pQueue) */
16 /* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
17 /* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
18 /* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
19 /* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
20 /* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
21 /* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
22 /* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
23 /* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
27 /* 02/25/00 Hav Khauv Initial version. */
28 /******************************************************************************/
36 /******************************************************************************/
37 /* Queue definitions. */
38 /******************************************************************************/
40 /* Entry for queueing. */
41 typedef void *PQQ_ENTRY
;
43 /* Linux Atomic Ops support */
44 typedef struct { int counter
; } atomic_t
;
48 * This combination of `inline' and `extern' has almost the effect of a
49 * macro. The way to use it is to put a function definition in a header
50 * file with these keywords, and put another copy of the definition
51 * (lacking `inline' and `extern') in a library file. The definition in
52 * the header file will cause most calls to the function to be inlined.
53 * If any uses of the function remain, they will refer to the single copy
57 atomic_set(atomic_t
* entry
, int val
)
62 atomic_read(atomic_t
* entry
)
64 return entry
->counter
;
67 atomic_inc(atomic_t
* entry
)
74 atomic_dec(atomic_t
* entry
)
81 atomic_sub(int a
, atomic_t
* entry
)
87 atomic_add(int a
, atomic_t
* entry
)
94 /* Queue header -- base type. */
101 } QQ_CONTAINER
, *PQQ_CONTAINER
;
104 /* Declare queue type macro. */
105 #define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
108 QQ_CONTAINER Container; \
109 PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
110 } _QUEUE_TYPE, *P##_QUEUE_TYPE
113 /******************************************************************************/
114 /* Compilation switches. */
115 /******************************************************************************/
118 #undef QQ_NO_OVERFLOW_CHECK
119 #undef QQ_NO_UNDERFLOW_CHECK
128 #endif /* QQ_NO_INLINE */
130 /******************************************************************************/
134 /******************************************************************************/
137 PQQ_CONTAINER pQueue
,
138 unsigned int QueueSize
) {
141 pQueue
->Size
= QueueSize
+1;
142 atomic_set(&pQueue
->EntryCnt
, 0);
146 /******************************************************************************/
150 /******************************************************************************/
153 PQQ_CONTAINER pQueue
) {
154 unsigned int NewHead
;
156 NewHead
= (pQueue
->Head
+ 1) % pQueue
->Size
;
158 return(NewHead
== pQueue
->Tail
);
162 /******************************************************************************/
166 /******************************************************************************/
169 PQQ_CONTAINER pQueue
) {
170 return(pQueue
->Head
== pQueue
->Tail
);
174 /******************************************************************************/
178 /******************************************************************************/
179 extern __inline
unsigned int
181 PQQ_CONTAINER pQueue
) {
186 /******************************************************************************/
190 /******************************************************************************/
191 extern __inline
unsigned int
193 PQQ_CONTAINER pQueue
) {
194 return atomic_read(&pQueue
->EntryCnt
);
195 } /* QQ_GetEntryCnt */
198 /******************************************************************************/
202 /* TRUE entry was added successfully. */
203 /* FALSE queue is full. */
204 /******************************************************************************/
207 PQQ_CONTAINER pQueue
,
211 Head
= (pQueue
->Head
+ 1) % pQueue
->Size
;
213 #if !defined(QQ_NO_OVERFLOW_CHECK)
214 if(Head
== pQueue
->Tail
) {
217 #endif /* QQ_NO_OVERFLOW_CHECK */
219 pQueue
->Array
[pQueue
->Head
] = pEntry
;
222 atomic_inc(&pQueue
->EntryCnt
);
228 /******************************************************************************/
232 /* TRUE entry was added successfully. */
233 /* FALSE queue is full. */
234 /******************************************************************************/
237 PQQ_CONTAINER pQueue
,
247 #if !defined(QQ_NO_OVERFLOW_CHECK)
248 if(Tail
== pQueue
->Head
) {
251 #endif /* QQ_NO_OVERFLOW_CHECK */
253 pQueue
->Array
[Tail
] = pEntry
;
256 atomic_inc(&pQueue
->EntryCnt
);
262 /******************************************************************************/
266 /******************************************************************************/
267 extern __inline PQQ_ENTRY
269 PQQ_CONTAINER pQueue
) {
275 #if !defined(QQ_NO_UNDERFLOW_CHECK)
276 if(Head
== pQueue
->Tail
) {
277 return (PQQ_ENTRY
) 0;
279 #endif /* QQ_NO_UNDERFLOW_CHECK */
286 Entry
= pQueue
->Array
[Head
];
293 atomic_dec(&pQueue
->EntryCnt
);
299 /******************************************************************************/
303 /******************************************************************************/
304 extern __inline PQQ_ENTRY
306 PQQ_CONTAINER pQueue
) {
312 #if !defined(QQ_NO_UNDERFLOW_CHECK)
313 if(Tail
== pQueue
->Head
) {
314 return (PQQ_ENTRY
) 0;
316 #endif /* QQ_NO_UNDERFLOW_CHECK */
318 Entry
= pQueue
->Array
[Tail
];
324 pQueue
->Tail
= (Tail
+ 1) % pQueue
->Size
;
325 atomic_dec(&pQueue
->EntryCnt
);
331 /******************************************************************************/
335 /******************************************************************************/
336 extern __inline PQQ_ENTRY
338 PQQ_CONTAINER pQueue
,
341 if(Idx
>= atomic_read(&pQueue
->EntryCnt
))
343 return (PQQ_ENTRY
) 0;
346 if(pQueue
->Head
> Idx
)
348 Idx
= pQueue
->Head
- Idx
;
352 Idx
= pQueue
->Size
- (Idx
- pQueue
->Head
);
356 return pQueue
->Array
[Idx
];
360 /******************************************************************************/
364 /******************************************************************************/
365 extern __inline PQQ_ENTRY
367 PQQ_CONTAINER pQueue
,
370 if(Idx
>= atomic_read(&pQueue
->EntryCnt
))
372 return (PQQ_ENTRY
) 0;
376 if(Idx
>= pQueue
->Size
)
378 Idx
= Idx
- pQueue
->Size
;
381 return pQueue
->Array
[Idx
];
384 #endif /* QQ_USE_MACROS */