]>
Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
1da177e4 LT |
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 | *----------------------------------------------------------------------------- | |
1da177e4 LT |
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 | ||
1beb6fa8 | 42 | static inline struct sym_quehead *sym_que_first(struct sym_quehead *head) |
1da177e4 LT |
43 | { |
44 | return (head->flink == head) ? 0 : head->flink; | |
45 | } | |
46 | ||
1beb6fa8 | 47 | static inline struct sym_quehead *sym_que_last(struct sym_quehead *head) |
1da177e4 LT |
48 | { |
49 | return (head->blink == head) ? 0 : head->blink; | |
50 | } | |
51 | ||
1beb6fa8 | 52 | static inline void __sym_que_add(struct sym_quehead * new, |
1da177e4 LT |
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 | ||
1beb6fa8 | 62 | static inline void __sym_que_del(struct sym_quehead * blink, |
1da177e4 LT |
63 | struct sym_quehead * flink) |
64 | { | |
65 | flink->blink = blink; | |
66 | blink->flink = flink; | |
67 | } | |
68 | ||
1beb6fa8 | 69 | static inline int sym_que_empty(struct sym_quehead *head) |
1da177e4 LT |
70 | { |
71 | return head->flink == head; | |
72 | } | |
73 | ||
1beb6fa8 | 74 | static inline void sym_que_splice(struct sym_quehead *list, |
1da177e4 LT |
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 | ||
1beb6fa8 | 91 | static inline void sym_que_move(struct sym_quehead *orig, |
1da177e4 LT |
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 | ||
d7f305e9 | 111 | #define sym_que_entry(ptr, type, member) container_of(ptr, type, member) |
1da177e4 LT |
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 | ||
1beb6fa8 | 119 | static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head) |
1da177e4 LT |
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 | ||
1beb6fa8 | 132 | static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head) |
1da177e4 LT |
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 */ |