1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3 *
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7 *following disclaimer.
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
11 *
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20 *
21 *
22 ********************************************************************************/
23 /*******************************************************************************/
24 /** \file
25  *
26  * The file defines list data structures for SAS/SATA TD layer
27  *
28  */
29 
30 #ifndef __TDLIST_H__
31 #define __TDLIST_H__
32 
33 
34 typedef struct tdList_s tdList_t;
35 
36 struct tdList_s {
37   tdList_t  *flink;
38   tdList_t  *blink;
39 };
40 
41 #define TDLIST_NEXT_ENTRY(ptr, type, member)        \
42   container_of((ptr)->flink, type, member)
43 
44 #define TDLIST_INIT_HDR(hdr)                        \
45   do {                                              \
46     ((tdList_t *)(hdr))->flink = (tdList_t *)(hdr); \
47     ((tdList_t *)(hdr))->blink = (tdList_t *)(hdr); \
48   } while (0)
49 
50 #define TDLIST_INIT_ELEMENT(hdr)                     \
51   do {                                               \
52     ((tdList_t *)(hdr))->flink = (tdList_t *)agNULL; \
53     ((tdList_t *)(hdr))->blink = (tdList_t *)agNULL; \
54   } while (0)
55 
56 #define TDLIST_ENQUEUE_AT_HEAD(toAddHdr,listHdr)                                \
57   do {                                                                          \
58     ((tdList_t *)(toAddHdr))->flink           = ((tdList_t *)(listHdr))->flink; \
59     ((tdList_t *)(toAddHdr))->blink           = (tdList_t *)(listHdr) ;         \
60     ((tdList_t *)(listHdr))->flink->blink     = (tdList_t *)(toAddHdr);         \
61     ((tdList_t *)(listHdr))->flink            = (tdList_t *)(toAddHdr);         \
62   } while (0)
63 
64 #define TDLIST_ENQUEUE_AT_TAIL(toAddHdr,listHdr)                                \
65   do {                                                                          \
66     ((tdList_t *)(toAddHdr))->flink           = (tdList_t *)(listHdr);          \
67     ((tdList_t *)(toAddHdr))->blink           = ((tdList_t *)(listHdr))->blink; \
68     ((tdList_t *)(listHdr))->blink->flink     = (tdList_t *)(toAddHdr);         \
69     ((tdList_t *)(listHdr))->blink            = (tdList_t *)(toAddHdr);         \
70   } while (0)
71 
72 #define TDLIST_EMPTY(listHdr) \
73   (((tdList_t *)(listHdr))->flink == ((tdList_t *)(listHdr)))
74 
75 #define TDLIST_NOT_EMPTY(listHdr) \
76   (!TDLIST_EMPTY(listHdr))
77 
78 #define TDLIST_DEQUEUE_THIS(hdr)                                      \
79   do {                                                                \
80     ((tdList_t *)(hdr))->blink->flink = ((tdList_t *)(hdr))->flink;   \
81     ((tdList_t *)(hdr))->flink->blink = ((tdList_t *)(hdr))->blink;   \
82     ((tdList_t *)(hdr))->flink = ((tdList_t *)(hdr))->blink = agNULL; \
83   } while (0)
84 
85 #define TDLIST_DEQUEUE_FROM_HEAD_FAST(atHeadHdr,listHdr)                              \
86   do {                                                                                \
87     *((tdList_t **)(atHeadHdr))                 = ((tdList_t *)(listHdr))->flink;     \
88     (*((tdList_t **)(atHeadHdr)))->flink->blink = (tdList_t *)(listHdr);              \
89     ((tdList_t *)(listHdr))->flink              = (*(tdList_t **)(atHeadHdr))->flink; \
90   } while (0)
91 
92 #define TDLIST_DEQUEUE_FROM_HEAD(atHeadHdr,listHdr)             \
93 do {                                                            \
94   if (TDLIST_NOT_EMPTY((listHdr)))                              \
95   {                                                             \
96     TDLIST_DEQUEUE_FROM_HEAD_FAST(atHeadHdr,listHdr);           \
97   }                                                             \
98   else                                                          \
99   {                                                             \
100     (*((tdList_t **)(atHeadHdr))) = (tdList_t *)agNULL;         \
101   }                                                             \
102 } while (0)
103 
104 #define TDLIST_DEQUEUE_FROM_TAIL_FAST(atTailHdr,listHdr)                                \
105   do {                                                                                  \
106     (*((tdList_t **)(atTailHdr)))               = ((tdList_t *)(listHdr))->blink;       \
107     (*((tdList_t **)(atTailHdr)))->blink->flink = (tdList_t *)(listHdr);                \
108     ((tdList_t *)(listHdr))->blink              = (*((tdList_t **)(atTailHdr)))->blink; \
109   } while (0)
110 
111 #define TDLIST_DEQUEUE_FROM_TAIL(atTailHdr,listHdr)               \
112   do {                                                            \
113     if (TDLIST_NOT_EMPTY((listHdr)))                              \
114     {                                                             \
115       TDLIST_DEQUEUE_FROM_TAIL_FAST(atTailHdr,listHdr);           \
116     }                                                             \
117     else                                                          \
118     {                                                             \
119       (*((tdList_t **)(atTailHdr))) = (tdList_t *)agNULL;         \
120     }                                                             \
121   } while (0)
122 
123 #define TDLIST_ENQUEUE_LIST_AT_TAIL_FAST(toAddListHdr, listHdr)               \
124   do {                                                                        \
125     ((tdList_t *)toAddListHdr)->blink->flink = ((tdList_t *)listHdr);         \
126     ((tdList_t *)toAddListHdr)->flink->blink = ((tdList_t *)listHdr)->blink;  \
127     ((tdList_t *)listHdr)->blink->flink = ((tdList_t *)toAddListHdr)->flink;  \
128     ((tdList_t *)listHdr)->blink = ((tdList_t *)toAddListHdr)->blink;         \
129     TDLIST_INIT_HDR(toAddListHdr);                                            \
130   } while (0)
131 
132 #define TDLIST_ENQUEUE_LIST_AT_TAIL(toAddListHdr, listHdr)                    \
133   do {                                                                        \
134     if (TDLIST_NOT_EMPTY(toAddListHdr))                                       \
135     {                                                                         \
136       TDLIST_ENQUEUE_LIST_AT_TAIL_FAST(toAddListHdr, listHdr);                \
137     }                                                                         \
138   } while (0)
139 
140 #define TDLIST_ENQUEUE_LIST_AT_HEAD_FAST(toAddListHdr, listHdr)               \
141   do {                                                                        \
142     ((tdList_t *)toAddListHdr)->blink->flink = ((tdList_t *)listHdr)->flink;  \
143     ((tdList_t *)toAddListHdr)->flink->blink = ((tdList_t *)listHdr);         \
144     ((tdList_t *)listHdr)->flink->blink = ((tdList_t *)toAddListHdr)->blink;  \
145     ((tdList_t *)listHdr)->flink = ((tdList_t *)toAddListHdr)->flink;         \
146     TDLIST_INIT_HDR(toAddListHdr);                                            \
147   } while (0)
148 
149 #define TDLIST_ENQUEUE_LIST_AT_HEAD(toAddListHdr, listHdr)                    \
150   do {                                                                        \
151     if (TDLIST_NOT_EMPTY(toAddListHdr))                                       \
152     {                                                                         \
153       TDLIST_ENQUEUE_LIST_AT_HEAD_FAST(toAddListHdr, listHdr);                \
154     }                                                                         \
155   } while (0)
156 
157 #define TD_FIELD_OFFSET(baseType,fieldName) \
158                     ((bit32)((bitptr)(&(((baseType *)0)->fieldName))))
159 
160 #define TDLIST_OBJECT_BASE(baseType,fieldName,fieldPtr)         \
161                     (void *)fieldPtr == (void *)0 ? (baseType *)0 :             \
162                     ((baseType *)((bit8 *)(fieldPtr) - ((bitptr)(&(((baseType *)0)->fieldName)))))
163 
164 
165 
166 #endif /* __TDLIST_H__ */
167 
168