1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 4 * of PCI-SCSI IO processors. 5 * 6 * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 7 * 8 * This driver is derived from the Linux sym53c8xx driver. 9 * Copyright (C) 1998-2000 Gerard Roudier 10 * 11 * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 12 * a port of the FreeBSD ncr driver to Linux-1.2.13. 13 * 14 * The original ncr driver has been written for 386bsd and FreeBSD by 15 * Wolfgang Stanglmeier <wolf@cologne.de> 16 * Stefan Esser <se@mi.Uni-Koeln.de> 17 * Copyright (C) 1994 Wolfgang Stanglmeier 18 * 19 * Other major contributions: 20 * 21 * NVRAM detection and reading. 22 * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 23 * 24 *----------------------------------------------------------------------------- 25 */ 26 27 #ifndef SYM_MISC_H 28 #define SYM_MISC_H 29 30 /* 31 * A la VMS/CAM-3 queue management. 32 */ 33 typedef struct sym_quehead { 34 struct sym_quehead *flink; /* Forward pointer */ 35 struct sym_quehead *blink; /* Backward pointer */ 36 } SYM_QUEHEAD; 37 38 #define sym_que_init(ptr) do { \ 39 (ptr)->flink = (ptr); (ptr)->blink = (ptr); \ 40 } while (0) 41 42 static inline struct sym_quehead *sym_que_first(struct sym_quehead *head) 43 { 44 return (head->flink == head) ? 0 : head->flink; 45 } 46 47 static inline struct sym_quehead *sym_que_last(struct sym_quehead *head) 48 { 49 return (head->blink == head) ? 0 : head->blink; 50 } 51 52 static inline void __sym_que_add(struct sym_quehead * new, 53 struct sym_quehead * blink, 54 struct sym_quehead * flink) 55 { 56 flink->blink = new; 57 new->flink = flink; 58 new->blink = blink; 59 blink->flink = new; 60 } 61 62 static inline void __sym_que_del(struct sym_quehead * blink, 63 struct sym_quehead * flink) 64 { 65 flink->blink = blink; 66 blink->flink = flink; 67 } 68 69 static inline int sym_que_empty(struct sym_quehead *head) 70 { 71 return head->flink == head; 72 } 73 74 static inline void sym_que_splice(struct sym_quehead *list, 75 struct sym_quehead *head) 76 { 77 struct sym_quehead *first = list->flink; 78 79 if (first != list) { 80 struct sym_quehead *last = list->blink; 81 struct sym_quehead *at = head->flink; 82 83 first->blink = head; 84 head->flink = first; 85 86 last->flink = at; 87 at->blink = last; 88 } 89 } 90 91 static inline void sym_que_move(struct sym_quehead *orig, 92 struct sym_quehead *dest) 93 { 94 struct sym_quehead *first, *last; 95 96 first = orig->flink; 97 if (first != orig) { 98 first->blink = dest; 99 dest->flink = first; 100 last = orig->blink; 101 last->flink = dest; 102 dest->blink = last; 103 orig->flink = orig; 104 orig->blink = orig; 105 } else { 106 dest->flink = dest; 107 dest->blink = dest; 108 } 109 } 110 111 #define sym_que_entry(ptr, type, member) container_of(ptr, type, member) 112 113 #define sym_insque(new, pos) __sym_que_add(new, pos, (pos)->flink) 114 115 #define sym_remque(el) __sym_que_del((el)->blink, (el)->flink) 116 117 #define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink) 118 119 static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head) 120 { 121 struct sym_quehead *elem = head->flink; 122 123 if (elem != head) 124 __sym_que_del(head, elem->flink); 125 else 126 elem = NULL; 127 return elem; 128 } 129 130 #define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head) 131 132 static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head) 133 { 134 struct sym_quehead *elem = head->blink; 135 136 if (elem != head) 137 __sym_que_del(elem->blink, head); 138 else 139 elem = 0; 140 return elem; 141 } 142 143 /* 144 * This one may be useful. 145 */ 146 #define FOR_EACH_QUEUED_ELEMENT(head, qp) \ 147 for (qp = (head)->flink; qp != (head); qp = qp->flink) 148 /* 149 * FreeBSD does not offer our kind of queue in the CAM CCB. 150 * So, we have to cast. 151 */ 152 #define sym_qptr(p) ((struct sym_quehead *) (p)) 153 154 /* 155 * Simple bitmap operations. 156 */ 157 #define sym_set_bit(p, n) (((u32 *)(p))[(n)>>5] |= (1<<((n)&0x1f))) 158 #define sym_clr_bit(p, n) (((u32 *)(p))[(n)>>5] &= ~(1<<((n)&0x1f))) 159 #define sym_is_bit(p, n) (((u32 *)(p))[(n)>>5] & (1<<((n)&0x1f))) 160 161 /* 162 * The below round up/down macros are to be used with a constant 163 * as argument (sizeof(...) for example), for the compiler to 164 * optimize the whole thing. 165 */ 166 #define _U_(a,m) (a)<=(1<<m)?m: 167 168 /* 169 * Round up logarithm to base 2 of a 16 bit constant. 170 */ 171 #define _LGRU16_(a) \ 172 ( \ 173 _U_(a, 0)_U_(a, 1)_U_(a, 2)_U_(a, 3)_U_(a, 4)_U_(a, 5)_U_(a, 6)_U_(a, 7) \ 174 _U_(a, 8)_U_(a, 9)_U_(a,10)_U_(a,11)_U_(a,12)_U_(a,13)_U_(a,14)_U_(a,15) \ 175 16) 176 177 #endif /* SYM_MISC_H */ 178