sym_misc.h (4428B)
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 */ 33typedef 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 42static inline struct sym_quehead *sym_que_first(struct sym_quehead *head) 43{ 44 return (head->flink == head) ? 0 : head->flink; 45} 46 47static inline struct sym_quehead *sym_que_last(struct sym_quehead *head) 48{ 49 return (head->blink == head) ? 0 : head->blink; 50} 51 52static 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 62static 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 69static inline int sym_que_empty(struct sym_quehead *head) 70{ 71 return head->flink == head; 72} 73 74static 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 91static 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 119static 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 132static 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 */