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