Linux-2.6.12-rc2
[cascardo/linux.git] / drivers / scsi / qla2xxx / qla_listops.h
1 /******************************************************************************
2  *                  QLOGIC LINUX SOFTWARE
3  *
4  * QLogic ISP2x00 device driver for Linux 2.6.x
5  * Copyright (C) 2003-2004 QLogic Corporation
6  * (www.qlogic.com)
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  ******************************************************************************/
19
20 /* Management functions for various lists */
21
22 /* __add_to_done_queue()
23  * 
24  * Place SRB command on done queue.
25  *
26  * Input:
27  *      ha           = host pointer
28  *      sp           = srb pointer.
29  * Locking:
30  *      this function assumes the ha->list_lock is already taken
31  */
32 static inline void 
33 __add_to_done_queue(struct scsi_qla_host * ha, srb_t * sp)
34 {
35         /*
36         if (sp->state != SRB_NO_QUEUE_STATE && 
37                 sp->state != SRB_ACTIVE_STATE)
38                 BUG();
39         */
40
41         /* Place block on done queue */
42         sp->cmd->host_scribble = (unsigned char *) NULL;
43         sp->state = SRB_DONE_STATE;
44         list_add_tail(&sp->list,&ha->done_queue);
45         ha->done_q_cnt++;
46         sp->ha = ha;
47 }
48
49 static inline void 
50 __add_to_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
51 {
52         /*
53         if( sp->state != SRB_NO_QUEUE_STATE && 
54                 sp->state != SRB_ACTIVE_STATE)
55                 BUG();
56         */
57
58         /* Place block on retry queue */
59         list_add_tail(&sp->list,&ha->retry_queue);
60         ha->retry_q_cnt++;
61         sp->flags |= SRB_WATCHDOG;
62         sp->state = SRB_RETRY_STATE;
63         sp->ha = ha;
64 }
65
66 static inline void 
67 __add_to_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
68 {
69         /*
70         if( sp->state != SRB_NO_QUEUE_STATE && 
71                 sp->state != SRB_ACTIVE_STATE)
72                 BUG();
73         */
74
75         /* Place block on retry queue */
76         list_add_tail(&sp->list,&ha->scsi_retry_queue);
77         ha->scsi_retry_q_cnt++;
78         sp->state = SRB_SCSI_RETRY_STATE;
79         sp->ha = ha;
80 }
81
82 static inline void 
83 add_to_done_queue(struct scsi_qla_host * ha, srb_t * sp)
84 {
85         unsigned long flags;
86
87         spin_lock_irqsave(&ha->list_lock, flags);
88         __add_to_done_queue(ha,sp);
89         spin_unlock_irqrestore(&ha->list_lock, flags);
90 }
91
92 static inline void 
93 add_to_free_queue(struct scsi_qla_host * ha, srb_t * sp)
94 {
95         mempool_free(sp, ha->srb_mempool);
96 }
97
98 static inline void 
99 add_to_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
100 {
101         unsigned long flags;
102
103         spin_lock_irqsave(&ha->list_lock, flags);
104         __add_to_retry_queue(ha,sp);
105         spin_unlock_irqrestore(&ha->list_lock, flags);
106 }
107
108 static inline void 
109 add_to_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
110 {
111         unsigned long flags;
112
113         spin_lock_irqsave(&ha->list_lock, flags);
114         __add_to_scsi_retry_queue(ha,sp);
115         spin_unlock_irqrestore(&ha->list_lock, flags);
116 }
117
118 /*
119  * __del_from_retry_queue
120  *      Function used to remove a command block from the
121  *      watchdog timer queue.
122  *
123  *      Note: Must insure that command is on watchdog
124  *            list before calling del_from_retry_queue
125  *            if (sp->flags & SRB_WATCHDOG)
126  *
127  * Input: 
128  *      ha = adapter block pointer.
129  *      sp = srb pointer.
130  * Locking:
131  *      this function assumes the list_lock is already taken
132  */
133 static inline void 
134 __del_from_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
135 {
136         list_del_init(&sp->list);
137
138         sp->flags &= ~(SRB_WATCHDOG | SRB_BUSY);
139         sp->state = SRB_NO_QUEUE_STATE;
140         ha->retry_q_cnt--;
141 }
142
143 /*
144  * __del_from_scsi_retry_queue
145  *      Function used to remove a command block from the
146  *      scsi retry queue.
147  *
148  * Input: 
149  *      ha = adapter block pointer.
150  *      sp = srb pointer.
151  * Locking:
152  *      this function assumes the list_lock is already taken
153  */
154 static inline void 
155 __del_from_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
156 {
157         list_del_init(&sp->list);
158
159         ha->scsi_retry_q_cnt--;
160         sp->state = SRB_NO_QUEUE_STATE;
161 }
162
163 /*
164  * del_from_retry_queue
165  *      Function used to remove a command block from the
166  *      watchdog timer queue.
167  *
168  *      Note: Must insure that command is on watchdog
169  *            list before calling del_from_retry_queue
170  *            if (sp->flags & SRB_WATCHDOG)
171  *
172  * Input: 
173  *      ha = adapter block pointer.
174  *      sp = srb pointer.
175  * Locking:
176  *      this function takes and releases the list_lock
177  */
178 static inline void 
179 del_from_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
180 {
181         unsigned long flags;
182
183         /*      if (unlikely(!(sp->flags & SRB_WATCHDOG)))
184                         BUG();*/
185         spin_lock_irqsave(&ha->list_lock, flags);
186
187         /*      if (unlikely(list_empty(&ha->retry_queue)))
188                         BUG();*/
189
190         __del_from_retry_queue(ha,sp);
191
192         spin_unlock_irqrestore(&ha->list_lock, flags);
193 }
194 /*
195  * del_from_scsi_retry_queue
196  *      Function used to remove a command block from the
197  *      scsi retry queue.
198  *
199  * Input: 
200  *      ha = adapter block pointer.
201  *      sp = srb pointer.
202  * Locking:
203  *      this function takes and releases the list_lock
204  */
205 static inline void 
206 del_from_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
207 {
208         unsigned long flags;
209
210         spin_lock_irqsave(&ha->list_lock, flags);
211
212         /*      if (unlikely(list_empty(&ha->scsi_retry_queue)))
213                         BUG();*/
214
215         __del_from_scsi_retry_queue(ha,sp);
216
217         spin_unlock_irqrestore(&ha->list_lock, flags);
218 }
219
220 /*
221  * __add_to_pending_queue
222  *      Add the standard SCB job to the bottom of standard SCB commands.
223  *
224  * Input:
225  * COMPLETE!!!
226  *      q  = SCSI LU pointer.
227  *      sp = srb pointer.
228  *      SCSI_LU_Q lock must be already obtained.
229  */
230 static inline int 
231 __add_to_pending_queue(struct scsi_qla_host *ha, srb_t * sp)
232 {
233         int     empty;
234         /*
235         if( sp->state != SRB_NO_QUEUE_STATE &&
236                 sp->state != SRB_FREE_STATE &&
237                 sp->state != SRB_ACTIVE_STATE)
238                 BUG();
239         */
240
241         empty = list_empty(&ha->pending_queue);
242         list_add_tail(&sp->list, &ha->pending_queue);
243         ha->qthreads++;
244         sp->state = SRB_PENDING_STATE;
245
246         return (empty);
247 }
248
249 static inline void 
250 __add_to_pending_queue_head(struct scsi_qla_host *ha, srb_t * sp)
251 {
252         /*
253         if( sp->state != SRB_NO_QUEUE_STATE && 
254                 sp->state != SRB_FREE_STATE &&
255                 sp->state != SRB_ACTIVE_STATE)
256                 BUG();
257         */
258
259         list_add(&sp->list, &ha->pending_queue);
260         ha->qthreads++;
261         sp->state = SRB_PENDING_STATE;
262 }
263
264 static inline int
265 add_to_pending_queue(struct scsi_qla_host *ha, srb_t *sp)
266 {
267         int     empty;
268         unsigned long flags;
269
270         spin_lock_irqsave(&ha->list_lock, flags);
271         empty = __add_to_pending_queue(ha, sp);
272         spin_unlock_irqrestore(&ha->list_lock, flags);
273
274         return (empty);
275 }
276 static inline void
277 add_to_pending_queue_head(struct scsi_qla_host *ha, srb_t *sp)
278 {
279         unsigned long flags;
280
281         spin_lock_irqsave(&ha->list_lock, flags);
282         __add_to_pending_queue_head(ha, sp);
283         spin_unlock_irqrestore(&ha->list_lock, flags);
284 }
285
286 static inline void
287 __del_from_pending_queue(struct scsi_qla_host *ha, srb_t *sp)
288 {
289         list_del_init(&sp->list);
290         ha->qthreads--;
291         sp->state = SRB_NO_QUEUE_STATE;
292 }
293
294 /*
295  * Failover Stuff.
296  */
297 static inline void
298 __add_to_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
299 {
300         /*
301         if( sp->state != SRB_NO_QUEUE_STATE && 
302                 sp->state != SRB_ACTIVE_STATE)
303                 BUG();
304         */
305
306         list_add_tail(&sp->list,&ha->failover_queue);
307         ha->failover_cnt++;
308         sp->state = SRB_FAILOVER_STATE;
309         sp->ha = ha;
310 }
311
312 static inline void add_to_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
313 {
314         unsigned long flags;
315
316         spin_lock_irqsave(&ha->list_lock, flags);
317
318         __add_to_failover_queue(ha,sp);
319
320         spin_unlock_irqrestore(&ha->list_lock, flags);
321 }
322 static inline void __del_from_failover_queue(struct scsi_qla_host * ha, srb_t *
323                 sp)
324 {
325         ha->failover_cnt--;
326         list_del_init(&sp->list);
327         sp->state = SRB_NO_QUEUE_STATE;
328 }
329
330 static inline void del_from_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
331 {
332         unsigned long flags;
333
334         spin_lock_irqsave(&ha->list_lock, flags);
335
336         __del_from_failover_queue(ha,sp);
337
338         spin_unlock_irqrestore(&ha->list_lock, flags);
339 }
340
341 static inline void 
342 del_from_pending_queue(struct scsi_qla_host * ha, srb_t * sp)
343 {
344         unsigned long flags;
345
346         spin_lock_irqsave(&ha->list_lock, flags);
347
348         __del_from_pending_queue(ha,sp);
349
350         spin_unlock_irqrestore(&ha->list_lock, flags);
351 }