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