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(blink: head, flink: 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(blink: elem->blink, flink: 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 | |