2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 $
6 \brief Definition for simple doubly linked list operations.
8 In this file we define the simple doubly linked list data structure and its
9 operation MACROs and INLINE functions.
17 * 08 05 2010 yuche.tsai
19 * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error.
23 * Set RLM parameters and enable CNM channel manager
27 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
30 * [WPD00003833][MT6620 and MT5931] Driver migration
31 * [WPD00003833] [MT6620 and MT5931] Driver migration
38 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
39 * add WIFI to BORA source control
40 ** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461
41 ** Update driver to fix lint warning
42 ** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461
43 ** Update for Driver Review
44 ** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461
45 ** Add macro for checking valid list
46 ** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461
47 ** Add LINK_IS_INVALID macro
48 ** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461
56 /*******************************************************************************
57 * C O M P I L E R F L A G S
58 ********************************************************************************
61 /*******************************************************************************
62 * E X T E R N A L R E F E R E N C E S
63 ********************************************************************************
65 #include "gl_typedef.h"
68 /*******************************************************************************
70 ********************************************************************************
72 #define INVALID_LINK_POISON1 ((VOID *) 0x00100101) // May cause page fault & unalignment issue (data abort)
73 #define INVALID_LINK_POISON2 ((VOID *) 0x00100201) // Used to verify that nonbody uses non-initialized link entries.
76 /*******************************************************************************
78 ********************************************************************************
80 /* Simple Doubly Linked List Structures - Entry Part */
81 typedef struct _LINK_ENTRY_T {
82 struct _LINK_ENTRY_T *prNext, *prPrev;
83 } LINK_ENTRY_T, *P_LINK_ENTRY_T;
85 /* Simple Doubly Linked List Structures - List Part */
86 typedef struct _LINK_T {
87 P_LINK_ENTRY_T prNext;
88 P_LINK_ENTRY_T prPrev;
92 /*******************************************************************************
94 ********************************************************************************
97 /*******************************************************************************
98 * P R I V A T E D A T A
99 ********************************************************************************
102 /*******************************************************************************
104 ********************************************************************************
106 #if 0 // No one use it, temporarily mark it for [Lint - Info 773]
107 #define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 }
109 #define LINK_DECLARATION(rLink) \
110 struct _LINK_T rLink = LINK_ADDR(rLink)
113 #define LINK_INITIALIZE(prLink) \
115 ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \
116 ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \
117 ((P_LINK_T)(prLink))->u4NumElem = 0; \
120 #define LINK_ENTRY_INITIALIZE(prEntry) \
122 ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \
123 ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \
126 #define LINK_ENTRY_INVALID(prEntry) \
128 ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \
129 ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \
132 #define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink))
134 /* NOTE: We should do memory zero before any LINK been initiated, so we can check
135 * if it is valid before parsing the LINK.
137 #define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL)
139 #define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL)
142 #define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member)
144 /* Insert an entry into a link list's head */
145 #define LINK_INSERT_HEAD(prLink, prEntry) \
147 linkAdd(prEntry, prLink); \
148 ((prLink)->u4NumElem)++; \
152 /* Append an entry into a link list's tail */
153 #define LINK_INSERT_TAIL(prLink, prEntry) \
155 linkAddTail(prEntry, prLink); \
156 ((prLink)->u4NumElem)++; \
159 /* Peek head entry, but keep still in link list */
160 #define LINK_PEEK_HEAD(prLink, _type, _member) \
162 LINK_IS_EMPTY(prLink) ? \
163 NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \
166 /* Peek tail entry, but keep still in link list */
167 #define LINK_PEEK_TAIL(prLink, _type, _member) \
169 LINK_IS_EMPTY(prLink) ? \
170 NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \
173 /* Get first entry from a link list */
174 /* NOTE: We assume the link entry located at the beginning of "prEntry Type",
175 * so that we can cast the link entry to other data type without doubts.
176 * And this macro also decrease the total entry count at the same time.
178 #define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \
181 if (LINK_IS_EMPTY(prLink)) { \
182 prEntry = (_P_TYPE)NULL; \
185 prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \
186 linkDel((P_LINK_ENTRY_T)prEntry); \
187 ((prLink)->u4NumElem)--; \
191 /* Assume the link entry located at the beginning of prEntry Type.
192 * And also decrease the total entry count.
194 #define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \
198 linkDel((P_LINK_ENTRY_T)prEntry); \
199 ((prLink)->u4NumElem)--; \
202 /* Iterate over a link list */
203 #define LINK_FOR_EACH(prEntry, prLink) \
204 for (prEntry = (prLink)->prNext; \
205 prEntry != (P_LINK_ENTRY_T)(prLink); \
206 prEntry = (P_LINK_ENTRY_T)prEntry->prNext)
208 /* Iterate over a link list backwards */
209 #define LINK_FOR_EACH_PREV(prEntry, prLink) \
210 for (prEntry = (prLink)->prPrev; \
211 prEntry != (P_LINK_ENTRY_T)(prLink); \
212 prEntry = (P_LINK_ENTRY_T)prEntry->prPrev)
214 /* Iterate over a link list safe against removal of link entry */
215 #define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \
216 for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \
217 prEntry != (P_LINK_ENTRY_T)(prLink); \
218 prEntry = prNextEntry, prNextEntry = prEntry->prNext)
220 /* Iterate over a link list of given type */
221 #define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \
222 for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \
223 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
224 prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember))
226 /* Iterate backwards over a link list of given type */
227 #define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \
228 for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \
229 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
230 prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember))
232 /* Iterate over a link list of given type safe against removal of link entry */
233 #define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \
234 for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \
235 prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \
236 &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \
238 prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember))
240 /*******************************************************************************
241 * F U N C T I O N D E C L A R A T I O N S
242 ********************************************************************************
245 /*******************************************************************************
247 ********************************************************************************
249 /*----------------------------------------------------------------------------*/
251 * \brief This function is only for internal link list manipulation.
253 * \param[in] prNew Pointer of new link head
254 * \param[in] prPrev Pointer of previous link head
255 * \param[in] prNext Pointer of next link head
259 /*----------------------------------------------------------------------------*/
262 IN P_LINK_ENTRY_T prNew,
263 IN P_LINK_ENTRY_T prPrev,
264 IN P_LINK_ENTRY_T prNext
267 prNext->prPrev = prNew;
268 prNew->prNext = prNext;
269 prNew->prPrev = prPrev;
270 prPrev->prNext = prNew;
273 } /* end of __linkAdd() */
276 /*----------------------------------------------------------------------------*/
278 * \brief This function will add a new entry after the specified link head.
280 * \param[in] prNew New entry to be added
281 * \param[in] prHead Specified link head to add it after
285 /*----------------------------------------------------------------------------*/
288 IN P_LINK_ENTRY_T prNew,
292 __linkAdd(prNew, (P_LINK_ENTRY_T)prLink, prLink->prNext);
295 } /* end of linkAdd() */
298 /*----------------------------------------------------------------------------*/
300 * \brief This function will add a new entry before the specified link head.
302 * \param[in] prNew New entry to be added
303 * \param[in] prHead Specified link head to add it before
307 /*----------------------------------------------------------------------------*/
310 IN P_LINK_ENTRY_T prNew,
314 __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T)prLink);
317 } /* end of linkAddTail() */
320 /*----------------------------------------------------------------------------*/
322 * \brief This function is only for internal link list manipulation.
324 * \param[in] prPrev Pointer of previous link head
325 * \param[in] prNext Pointer of next link head
329 /*----------------------------------------------------------------------------*/
332 IN P_LINK_ENTRY_T prPrev,
333 IN P_LINK_ENTRY_T prNext
336 prNext->prPrev = prPrev;
337 prPrev->prNext = prNext;
340 } /* end of __linkDel() */
343 /*----------------------------------------------------------------------------*/
345 * \brief This function will delete a specified entry from link list.
346 * NOTE: the entry is in an initial state.
348 * \param prEntry Specified link head(entry)
352 /*----------------------------------------------------------------------------*/
355 IN P_LINK_ENTRY_T prEntry
358 __linkDel(prEntry->prPrev, prEntry->prNext);
360 LINK_ENTRY_INITIALIZE(prEntry);
363 } /* end of linkDel() */
366 /*----------------------------------------------------------------------------*/
368 * \brief This function will delete a specified entry from link list and then add it
369 * after the specified link head.
371 * \param[in] prEntry Specified link head(entry)
372 * \param[in] prOtherHead Another link head to add it after
376 /*----------------------------------------------------------------------------*/
379 IN P_LINK_ENTRY_T prEntry,
383 __linkDel(prEntry->prPrev, prEntry->prNext);
384 linkAdd(prEntry, prLink);
387 } /* end of linkMove() */
390 /*----------------------------------------------------------------------------*/
392 * \brief This function will delete a specified entry from link list and then add it
393 * before the specified link head.
395 * \param[in] prEntry Specified link head(entry)
396 * \param[in] prOtherHead Another link head to add it before
400 /*----------------------------------------------------------------------------*/
403 IN P_LINK_ENTRY_T prEntry,
407 __linkDel(prEntry->prPrev, prEntry->prNext);
408 linkAddTail(prEntry, prLink);
411 } /* end of linkMoveTail() */