ed3538c3ed7f6836df12666cc82662beb7986eda
[mirror/scst/.git] / scst / src / scst_targ.c
1 /*
2  *  scst_targ.c
3  *  
4  *  Copyright (C) 2004-2007 Vladislav Bolkhovitin <vst@vlnb.net>
5  *                 and Leonid Stoljar
6  *  
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation, version 2
10  *  of the License.
11  * 
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  */
17
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/list.h>
22 #include <linux/spinlock.h>
23 #include <linux/slab.h>
24 #include <linux/sched.h>
25 #include <linux/smp_lock.h>
26 #include <asm/unistd.h>
27 #include <asm/string.h>
28 #include <linux/kthread.h>
29 #include <linux/delay.h>
30
31 #include "scsi_tgt.h"
32 #include "scst_priv.h"
33
34 static void scst_cmd_set_sn(struct scst_cmd *cmd);
35 static int __scst_init_cmd(struct scst_cmd *cmd);
36
37 static inline void scst_schedule_tasklet(struct scst_cmd *cmd)
38 {
39         struct scst_tasklet *t = &scst_tasklets[smp_processor_id()];
40         unsigned long flags;
41
42         spin_lock_irqsave(&t->tasklet_lock, flags);
43         TRACE_DBG("Adding cmd %p to tasklet %d cmd list", cmd,
44                 smp_processor_id());
45         list_add_tail(&cmd->cmd_list_entry, &t->tasklet_cmd_list);
46         spin_unlock_irqrestore(&t->tasklet_lock, flags);
47
48         tasklet_schedule(&t->tasklet);
49 }
50
51 /* 
52  * Must not be called in parallel with scst_unregister_session() for the 
53  * same sess
54  */
55 struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
56                              const uint8_t *lun, int lun_len,
57                              const uint8_t *cdb, int cdb_len, int atomic)
58 {
59         struct scst_cmd *cmd;
60
61         TRACE_ENTRY();
62
63 #ifdef EXTRACHECKS
64         if (unlikely(sess->shut_phase != SCST_SESS_SPH_READY)) {
65                 PRINT_ERROR("%s", "New cmd while shutting down the session");
66                 sBUG();
67         }
68 #endif
69
70         cmd = scst_alloc_cmd(atomic ? GFP_ATOMIC : GFP_KERNEL);
71         if (cmd == NULL)
72                 goto out;
73
74         cmd->sess = sess;
75         cmd->tgt = sess->tgt;
76         cmd->tgtt = sess->tgt->tgtt;
77
78         /* 
79          * For both wrong lun and CDB defer the error reporting for
80          * scst_cmd_init_done()
81          */
82
83         cmd->lun = scst_unpack_lun(lun, lun_len);
84
85         if (cdb_len <= SCST_MAX_CDB_SIZE) {
86                 memcpy(cmd->cdb, cdb, cdb_len);
87                 cmd->cdb_len = cdb_len;
88         }
89
90         TRACE_DBG("cmd %p, sess %p", cmd, sess);
91         scst_sess_get(sess);
92
93 out:
94         TRACE_EXIT();
95         return cmd;
96 }
97
98 static int scst_init_cmd(struct scst_cmd *cmd, int context)
99 {
100         int rc;
101
102         TRACE_ENTRY();
103
104         /* See the comment in scst_do_job_init() */
105         if (unlikely(!list_empty(&scst_init_cmd_list))) {
106                 TRACE_MGMT_DBG("%s", "init cmd list busy");
107                 goto out_redirect;
108         }
109         smp_rmb();
110
111         rc = __scst_init_cmd(cmd);
112         if (unlikely(rc > 0))
113                 goto out_redirect;
114         else if (unlikely(rc != 0))
115                 goto out;
116
117         /* Small context optimization */
118         if (((context == SCST_CONTEXT_TASKLET) ||
119              (context == SCST_CONTEXT_DIRECT_ATOMIC)) && 
120             scst_cmd_is_expected_set(cmd)) {
121                 if (cmd->expected_data_direction == SCST_DATA_WRITE) {
122                         if ( !test_bit(SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC,
123                                         &cmd->tgt_dev->tgt_dev_flags))
124                                 context = SCST_CONTEXT_THREAD;
125                 } else {
126                         if ( !test_bit(SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC,
127                                         &cmd->tgt_dev->tgt_dev_flags))
128                                 context = SCST_CONTEXT_THREAD;
129                 }
130         }
131
132 out:
133         TRACE_EXIT_RES(context);
134         return context;
135
136 out_redirect:
137         if (cmd->preprocessing_only) {
138                 /*
139                  * Poor man solution for single threaded targets, where 
140                  * blocking receiver at least sometimes means blocking all.
141                  */
142                 sBUG_ON(context != SCST_CONTEXT_DIRECT);
143                 scst_set_busy(cmd);
144                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
145                 /* Keep initiator away from too many BUSY commands */
146                 if (!in_interrupt() && !in_atomic())
147                         msleep(50);
148                 else
149                         WARN_ON_ONCE(1);
150         } else {
151                 unsigned long flags;
152                 spin_lock_irqsave(&scst_init_lock, flags);
153                 TRACE_MGMT_DBG("Adding cmd %p to init cmd list (scst_cmd_count "
154                         "%d)", cmd, atomic_read(&scst_cmd_count));
155                 list_add_tail(&cmd->cmd_list_entry, &scst_init_cmd_list);
156                 if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
157                         scst_init_poll_cnt++;
158                 spin_unlock_irqrestore(&scst_init_lock, flags);
159                 wake_up(&scst_init_cmd_list_waitQ);
160                 context = -1;
161         }
162         goto out;
163 }
164
165 void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context)
166 {
167         unsigned long flags;
168         struct scst_session *sess = cmd->sess;
169
170         TRACE_ENTRY();
171
172         TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd);
173         TRACE(TRACE_SCSI, "tag=%llu, lun=%Ld, CDB len=%d", cmd->tag, 
174                 (uint64_t)cmd->lun, cmd->cdb_len);
175         TRACE_BUFF_FLAG(TRACE_SCSI|TRACE_RECV_BOT, "Recieving CDB",
176                 cmd->cdb, cmd->cdb_len);
177
178 #ifdef EXTRACHECKS
179         if (unlikely(in_irq()) && ((pref_context == SCST_CONTEXT_DIRECT) ||
180                          (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)))
181         {
182                 PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
183                         "SCST_CONTEXT_TASKLET instead\n", pref_context,
184                         cmd->tgtt->name);
185                 pref_context = SCST_CONTEXT_TASKLET;
186         }
187 #endif
188
189         atomic_inc(&sess->sess_cmd_count);
190
191         spin_lock_irqsave(&sess->sess_list_lock, flags);
192
193         list_add_tail(&cmd->search_cmd_list_entry, &sess->search_cmd_list);
194
195         if (unlikely(sess->init_phase != SCST_SESS_IPH_READY)) {
196                 switch(sess->init_phase) {
197                 case SCST_SESS_IPH_SUCCESS:
198                         break;
199                 case SCST_SESS_IPH_INITING:
200                         TRACE_DBG("Adding cmd %p to init deferred cmd list", cmd);
201                         list_add_tail(&cmd->cmd_list_entry, 
202                                 &sess->init_deferred_cmd_list);
203                         spin_unlock_irqrestore(&sess->sess_list_lock, flags);
204                         goto out;
205                 case SCST_SESS_IPH_FAILED:
206                         spin_unlock_irqrestore(&sess->sess_list_lock, flags);
207                         scst_set_busy(cmd);
208                         cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
209                         goto active;
210                 default:
211                         sBUG();
212                 }
213         }
214
215         spin_unlock_irqrestore(&sess->sess_list_lock, flags);
216
217         if (unlikely(cmd->lun == (lun_t)-1)) {
218                 PRINT_ERROR("Wrong LUN %d, finishing cmd", -1);
219                 scst_set_cmd_error(cmd,
220                         SCST_LOAD_SENSE(scst_sense_lun_not_supported));
221                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
222                 goto active;
223         }
224
225         if (unlikely(cmd->cdb_len == 0)) {
226                 PRINT_ERROR("Wrong CDB len %d, finishing cmd", 0);
227                 scst_set_cmd_error(cmd,
228                            SCST_LOAD_SENSE(scst_sense_invalid_opcode));
229                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
230                 goto active;
231         }
232
233         if (unlikely(cmd->queue_type >= SCST_CMD_QUEUE_ACA)) {
234                 PRINT_ERROR("Unsupported queue type %d", cmd->queue_type);
235                 scst_set_cmd_error(cmd,
236                         SCST_LOAD_SENSE(scst_sense_invalid_message));
237                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
238                 goto active;
239         }
240
241         cmd->state = SCST_CMD_STATE_INIT;
242         /* cmd must be inited here to keep the order */
243         pref_context = scst_init_cmd(cmd, pref_context);
244         if (unlikely(pref_context < 0))
245                 goto out;
246
247 active:
248         /* Here cmd must not be in any cmd list, no locks */
249         switch (pref_context) {
250         case SCST_CONTEXT_TASKLET:
251                 scst_schedule_tasklet(cmd);
252                 break;
253
254         case SCST_CONTEXT_DIRECT:
255         case SCST_CONTEXT_DIRECT_ATOMIC:
256                 scst_process_active_cmd(cmd, pref_context);
257                 /* For *NEED_THREAD wake_up() is already done */
258                 break;
259
260         default:
261                 PRINT_ERROR("Context %x is undefined, using the thread one",
262                         pref_context);
263                 /* go through */
264         case SCST_CONTEXT_THREAD:
265                 spin_lock_irqsave(&cmd->cmd_lists->cmd_list_lock, flags);
266                 TRACE_DBG("Adding cmd %p to active cmd list", cmd);
267                 if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
268                         list_add(&cmd->cmd_list_entry,
269                                 &cmd->cmd_lists->active_cmd_list);
270                 else
271                         list_add_tail(&cmd->cmd_list_entry,
272                                 &cmd->cmd_lists->active_cmd_list);
273                 wake_up(&cmd->cmd_lists->cmd_list_waitQ);
274                 spin_unlock_irqrestore(&cmd->cmd_lists->cmd_list_lock, flags);
275                 break;
276         }
277
278 out:
279         TRACE_EXIT();
280         return;
281 }
282
283 static int scst_pre_parse(struct scst_cmd *cmd)
284 {
285         int res = SCST_CMD_STATE_RES_CONT_SAME;
286         struct scst_device *dev = cmd->dev;
287
288         TRACE_ENTRY();
289
290         cmd->inc_expected_sn_on_done = !dev->has_own_order_mgmt;
291
292         sBUG_ON(cmd->internal);
293
294         /*
295          * Expected transfer data supplied by the SCSI transport via the
296          * target driver are untrusted, so we prefer to fetch them from CDB.
297          * Additionally, not all transports support supplying the expected
298          * transfer data.
299          */
300
301         if (unlikely(scst_get_cdb_info(cmd->cdb, dev->handler->type, 
302                         &cmd->op_flags, &cmd->data_direction,
303                         &cmd->bufflen, &cmd->cdb_len, &cmd->op_name) != 0)) {
304                 PRINT_ERROR("Unknown opcode 0x%02x for %s. "
305                         "Should you update scst_scsi_op_table?",
306                         cmd->cdb[0], dev->handler->name);
307 #ifdef USE_EXPECTED_VALUES
308                 if (scst_cmd_is_expected_set(cmd)) {
309                         TRACE(TRACE_SCSI, "Using initiator supplied values: "
310                                 "direction %d, transfer_len %d",
311                                 cmd->expected_data_direction,
312                                 cmd->expected_transfer_len);
313                         cmd->data_direction = cmd->expected_data_direction;
314                         
315                         cmd->bufflen = cmd->expected_transfer_len;
316                         /* Restore (likely) lost CDB length */
317                         cmd->cdb_len = scst_get_cdb_len(cmd->cdb);
318                         if (cmd->cdb_len == -1) {
319                                 PRINT_ERROR("Unable to get CDB length for "
320                                         "opcode 0x%02x. Returning INVALID "
321                                         "OPCODE", cmd->cdb[0]);
322                                 scst_set_cmd_error(cmd,
323                                    SCST_LOAD_SENSE(scst_sense_invalid_opcode));
324                                 goto out_xmit;
325                         }
326                 } else {
327                         PRINT_ERROR("Unknown opcode 0x%02x for %s and "
328                              "target %s not supplied expected values",
329                              cmd->cdb[0], dev->handler->name, cmd->tgtt->name);
330                         scst_set_cmd_error(cmd,
331                                    SCST_LOAD_SENSE(scst_sense_invalid_opcode));
332                         goto out_xmit;
333                 }
334 #else
335                 scst_set_cmd_error(cmd,
336                            SCST_LOAD_SENSE(scst_sense_invalid_opcode));
337                 goto out_xmit;
338 #endif
339         } else {
340                 TRACE(TRACE_SCSI, "op_name <%s>, direction=%d (expected %d, "
341                         "set %s), transfer_len=%d (expected len %d), flags=%d",
342                         cmd->op_name, cmd->data_direction,
343                         cmd->expected_data_direction,
344                         scst_cmd_is_expected_set(cmd) ? "yes" : "no",
345                         cmd->bufflen, cmd->expected_transfer_len, cmd->op_flags);
346
347                 if (unlikely((cmd->op_flags & SCST_UNKNOWN_LENGTH) != 0)) {
348                         if (scst_cmd_is_expected_set(cmd)) {
349                                 /*
350                                  * Command data length can't be easily
351                                  * determined from the CDB. ToDo, that should 
352                                  * be fixed. Until it's fixed, get it from
353                                  * the supplied expected value, but
354                                  * limit it to some reasonable value (15MB).
355                                  */
356                                 cmd->bufflen = min(cmd->expected_transfer_len,
357                                                         15*1024*1024);
358                         } else
359                                 cmd->bufflen = 0;
360                 }
361         }
362
363         if (unlikely(cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT)) {
364                 PRINT_ERROR("NACA bit in control byte CDB is not supported "
365                             "(opcode 0x%02x)", cmd->cdb[0]);
366                 scst_set_cmd_error(cmd,
367                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
368                 goto out_xmit;
369         }
370
371         if (unlikely(cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT)) {
372                 PRINT_ERROR("Linked commands are not supported "
373                             "(opcode 0x%02x)", cmd->cdb[0]);
374                 scst_set_cmd_error(cmd,
375                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
376                 goto out_xmit;
377         }
378
379         cmd->state = SCST_CMD_STATE_DEV_PARSE;
380
381 out:
382         TRACE_EXIT_RES(res);
383         return res;
384
385 out_xmit:
386         cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
387         res = SCST_CMD_STATE_RES_CONT_SAME;
388         goto out;
389 }
390
391 static int scst_parse_cmd(struct scst_cmd *cmd)
392 {
393         int res = SCST_CMD_STATE_RES_CONT_SAME;
394         int state;
395         struct scst_device *dev = cmd->dev;
396         int atomic = scst_cmd_atomic(cmd);
397         int orig_bufflen = cmd->bufflen;
398         scst_data_direction orig_data_direction = cmd->data_direction;
399
400         TRACE_ENTRY();
401
402         if (atomic && !dev->handler->parse_atomic) {
403                 TRACE_DBG("Dev handler %s parse() can not be "
404                       "called in atomic context, rescheduling to the thread",
405                       dev->handler->name);
406                 res = SCST_CMD_STATE_RES_NEED_THREAD;
407                 goto out;
408         }
409
410         if (likely(!scst_is_cmd_local(cmd))) {
411                 TRACE_DBG("Calling dev handler %s parse(%p)",
412                       dev->handler->name, cmd);
413                 TRACE_BUFF_FLAG(TRACE_SEND_BOT, "Parsing: ", cmd->cdb, cmd->cdb_len);
414                 state = dev->handler->parse(cmd);
415                 /* Caution: cmd can be already dead here */
416                 TRACE_DBG("Dev handler %s parse() returned %d",
417                         dev->handler->name, state);
418
419                 switch (state) {
420                 case SCST_CMD_STATE_NEED_THREAD_CTX:
421                         TRACE_DBG("Dev handler %s parse() requested thread "
422                               "context, rescheduling", dev->handler->name);
423                         res = SCST_CMD_STATE_RES_NEED_THREAD;
424                         goto out;
425
426                 case SCST_CMD_STATE_STOP:
427                         TRACE_DBG("Dev handler %s parse() requested stop "
428                                 "processing", dev->handler->name);
429                         res = SCST_CMD_STATE_RES_CONT_NEXT;
430                         goto out;
431                 }
432
433                 if (state == SCST_CMD_STATE_DEFAULT)
434                         state = SCST_CMD_STATE_PREPARE_SPACE;
435         } else
436                 state = SCST_CMD_STATE_PREPARE_SPACE;
437
438         if (cmd->data_len == -1)
439                 cmd->data_len = cmd->bufflen;
440
441         if (cmd->data_buf_alloced && unlikely((orig_bufflen > cmd->bufflen))) {
442                 PRINT_ERROR("Dev handler supplied data buffer (size %d), "
443                         "is less, than required (size %d)", cmd->bufflen,
444                         orig_bufflen);
445                 goto out_error;
446         }
447
448         if (unlikely(state == SCST_CMD_STATE_PRE_XMIT_RESP))
449                 goto set_res;
450
451 #ifdef EXTRACHECKS
452         if ((cmd->bufflen != 0) &&
453             ((cmd->data_direction == SCST_DATA_NONE) ||
454              ((cmd->sg == NULL) && (state > SCST_CMD_STATE_PREPARE_SPACE)))) {
455                 PRINT_ERROR("Dev handler %s parse() returned "
456                         "invalid cmd data_direction %d, bufflen %d, state %d "
457                         "or sg %p (opcode 0x%x)", dev->handler->name, 
458                         cmd->data_direction, cmd->bufflen, state, cmd->sg,
459                         cmd->cdb[0]);
460                 goto out_error;
461         }
462 #endif
463
464         if (scst_cmd_is_expected_set(cmd)) {
465 #ifdef USE_EXPECTED_VALUES
466 #       ifdef EXTRACHECKS
467                 if ((cmd->data_direction != cmd->expected_data_direction) ||
468                     (cmd->bufflen != cmd->expected_transfer_len)) {
469                         PRINT_ERROR("Expected values don't match decoded ones: "
470                                 "data_direction %d, expected_data_direction %d, "
471                                 "bufflen %d, expected_transfer_len %d",
472                                 cmd->data_direction, cmd->expected_data_direction,
473                                 cmd->bufflen, cmd->expected_transfer_len);
474                 }
475 #       endif
476                 cmd->data_direction = cmd->expected_data_direction;
477                 cmd->bufflen = cmd->expected_transfer_len;
478 #else
479                 if (unlikely(cmd->data_direction != orig_data_direction)) {
480                         PRINT_ERROR("Expected data direction %d for opcode "
481                                 "0x%02x (handler %s, target %s) doesn't match "
482                                 "decoded value %d", cmd->data_direction,
483                                 cmd->cdb[0], dev->handler->name,
484                                 cmd->tgtt->name, orig_data_direction);
485                         scst_set_cmd_error(cmd,
486                                 SCST_LOAD_SENSE(scst_sense_invalid_message));
487                         goto out_dev_done;
488                 }
489                 if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) {
490                         PRINT_INFO("Warning: expected transfer length %d for "
491                                 "opcode 0x%02x (handler %s, target %s) doesn't "
492                                 "match decoded value %d. Faulty initiator "
493                                 "(e.g. VMware is known to be such) or "
494                                 "scst_scsi_op_table should be updated?",
495                                 cmd->expected_transfer_len, cmd->cdb[0],
496                                 dev->handler->name, cmd->tgtt->name,
497                                 cmd->bufflen);
498                         PRINT_BUFFER("Suspicious CDB", cmd->cdb, cmd->cdb_len);
499                 }
500 #endif
501         }
502
503         if ((cmd->data_direction == SCST_DATA_UNKNOWN) ||
504             ((cmd->bufflen == 0) && (cmd->data_direction != SCST_DATA_NONE))) {
505                 PRINT_ERROR("Wrong data direction (%d) or/and buffer "
506                         "length (%d). Opcode 0x%x, handler %s, target %s",
507                         cmd->data_direction, cmd->bufflen, cmd->cdb[0],
508                         dev->handler->name, cmd->tgtt->name);
509                 goto out_error;
510         }
511
512 set_res:
513         switch (state) {
514         case SCST_CMD_STATE_PREPARE_SPACE:
515         case SCST_CMD_STATE_PRE_PARSE:
516         case SCST_CMD_STATE_DEV_PARSE:
517         case SCST_CMD_STATE_RDY_TO_XFER:
518         case SCST_CMD_STATE_TGT_PRE_EXEC:
519         case SCST_CMD_STATE_SEND_TO_MIDLEV:
520         case SCST_CMD_STATE_PRE_DEV_DONE:
521         case SCST_CMD_STATE_DEV_DONE:
522         case SCST_CMD_STATE_PRE_XMIT_RESP:
523         case SCST_CMD_STATE_XMIT_RESP:
524         case SCST_CMD_STATE_FINISHED:
525                 cmd->state = state;
526                 res = SCST_CMD_STATE_RES_CONT_SAME;
527                 break;
528
529         default:
530                 if (state >= 0) {
531                         PRINT_ERROR("Dev handler %s parse() returned "
532                              "invalid cmd state %d (opcode %d)", 
533                              dev->handler->name, state, cmd->cdb[0]);
534                 } else {
535                         PRINT_ERROR("Dev handler %s parse() returned "
536                                 "error %d (opcode %d)", dev->handler->name, 
537                                 state, cmd->cdb[0]);
538                 }
539                 goto out_error;
540         }
541
542         if (cmd->resp_data_len == -1) {
543                 if (cmd->data_direction == SCST_DATA_READ)
544                         cmd->resp_data_len = cmd->bufflen;
545                 else
546                          cmd->resp_data_len = 0;
547         }
548         
549 out:
550         TRACE_EXIT_HRES(res);
551         return res;
552
553 out_error:
554         /* dev_done() will be called as part of the regular cmd's finish */
555         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
556
557 #ifndef USE_EXPECTED_VALUES
558 out_dev_done:
559 #endif
560         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
561         res = SCST_CMD_STATE_RES_CONT_SAME;
562         goto out;
563 }
564
565 static int scst_prepare_space(struct scst_cmd *cmd)
566 {
567         int r = 0, res = SCST_CMD_STATE_RES_CONT_SAME;
568
569         TRACE_ENTRY();
570
571         if (cmd->data_direction == SCST_DATA_NONE)
572                 goto prep_done;
573
574         if (cmd->data_buf_tgt_alloc) {
575                 int orig_bufflen = cmd->bufflen;
576
577                 TRACE_MEM("%s", "Custom tgt data buf allocation requested");
578
579                 r = cmd->tgtt->alloc_data_buf(cmd);
580                 if (r > 0)
581                         goto alloc;
582                 else if (r == 0) {
583                         cmd->data_buf_alloced = 1;
584                         if (unlikely(orig_bufflen < cmd->bufflen)) {
585                                 PRINT_ERROR("Target driver allocated data "
586                                         "buffer (size %d), is less, than "
587                                         "required (size %d)", orig_bufflen,
588                                         cmd->bufflen);
589                                 goto out_error;
590                         }
591                 } else
592                         goto check;
593         }
594
595 alloc:
596         if (!cmd->data_buf_alloced) {
597                 r = scst_alloc_space(cmd);
598         } else {
599                 TRACE_MEM("%s", "data_buf_alloced set, returning");
600         }
601         
602 check:
603         if (r != 0) {
604                 if (scst_cmd_atomic(cmd)) {
605                         TRACE_MEM("%s", "Atomic memory allocation failed, "
606                               "rescheduling to the thread");
607                         res = SCST_CMD_STATE_RES_NEED_THREAD;
608                         goto out;
609                 } else
610                         goto out_no_space;
611         }
612
613 prep_done:
614         if (cmd->preprocessing_only) {
615                 if (scst_cmd_atomic(cmd) && 
616                     !cmd->tgtt->preprocessing_done_atomic) {
617                         TRACE_DBG("%s", "preprocessing_done() can not be "
618                               "called in atomic context, rescheduling to "
619                               "the thread");
620                         res = SCST_CMD_STATE_RES_NEED_THREAD;
621                         goto out;
622                 }
623
624                 if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
625                         TRACE_MGMT_DBG("ABORTED set, returning ABORTED for "
626                                 "cmd %p", cmd);
627                         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
628                         res = SCST_CMD_STATE_RES_CONT_SAME;
629                         goto out;
630                 }
631
632                 res = SCST_CMD_STATE_RES_CONT_NEXT;
633                 cmd->state = SCST_CMD_STATE_PREPROCESS_DONE;
634
635                 TRACE_DBG("Calling preprocessing_done(cmd %p)", cmd);
636                 cmd->tgtt->preprocessing_done(cmd);
637                 TRACE_DBG("%s", "preprocessing_done() returned");
638                 goto out;
639
640         }
641
642         switch (cmd->data_direction) {
643         case SCST_DATA_WRITE:
644                 cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
645                 break;
646
647         default:
648                 cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
649                 break;
650         }
651
652 out:
653         TRACE_EXIT_HRES(res);
654         return res;
655
656 out_no_space:
657         TRACE(TRACE_OUT_OF_MEM, "Unable to allocate or build requested buffer "
658                 "(size %d), sending BUSY or QUEUE FULL status", cmd->bufflen);
659         scst_set_busy(cmd);
660         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
661         res = SCST_CMD_STATE_RES_CONT_SAME;
662         goto out;
663
664 out_error:
665         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
666         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
667         res = SCST_CMD_STATE_RES_CONT_SAME;
668         goto out;
669 }
670
671 void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context)
672 {
673         TRACE_ENTRY();
674
675         TRACE_DBG("Preferred context: %d", pref_context);
676         TRACE_DBG("tag=%llu, status=%#x", scst_cmd_get_tag(cmd), status);
677
678 #ifdef EXTRACHECKS
679         if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) ||
680                          (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)))
681         {
682                 PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
683                         "SCST_CONTEXT_TASKLET instead\n", pref_context,
684                         cmd->tgtt->name);
685                 pref_context = SCST_CONTEXT_TASKLET;
686         }
687 #endif
688
689         switch (status) {
690         case SCST_PREPROCESS_STATUS_SUCCESS:
691                 switch (cmd->data_direction) {
692                 case SCST_DATA_WRITE:
693                         cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
694                         break;
695                 default:
696                         cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
697                         break;
698                 }
699                 if (cmd->set_sn_on_restart_cmd)
700                         scst_cmd_set_sn(cmd);
701                 /* Small context optimization */
702                 if ((pref_context == SCST_CONTEXT_TASKLET) || 
703                     (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)) {
704                         if (cmd->data_direction == SCST_DATA_WRITE) {
705                                 if ( !test_bit(SCST_TGT_DEV_AFTER_RESTART_WR_ATOMIC,
706                                                 &cmd->tgt_dev->tgt_dev_flags))
707                                         pref_context = SCST_CONTEXT_THREAD;
708                         } else {
709                                 if ( !test_bit(SCST_TGT_DEV_AFTER_RESTART_OTH_ATOMIC,
710                                                 &cmd->tgt_dev->tgt_dev_flags))
711                                         pref_context = SCST_CONTEXT_THREAD;
712                         }
713                 }
714                 break;
715
716         case SCST_PREPROCESS_STATUS_ERROR_SENSE_SET:
717                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
718                 break;
719
720         case SCST_PREPROCESS_STATUS_ERROR_FATAL:
721                 set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
722                 /* go through */
723         case SCST_PREPROCESS_STATUS_ERROR:
724                 scst_set_cmd_error(cmd,
725                            SCST_LOAD_SENSE(scst_sense_hardw_error));
726                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
727                 break;
728
729         default:
730                 PRINT_ERROR("%s() received unknown status %x", __func__,
731                         status);
732                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
733                 break;
734         }
735
736         scst_proccess_redirect_cmd(cmd, pref_context, 1);
737
738         TRACE_EXIT();
739         return;
740 }
741
742 /* No locks */
743 static int scst_queue_retry_cmd(struct scst_cmd *cmd, int finished_cmds)
744 {
745         struct scst_tgt *tgt = cmd->sess->tgt;
746         int res = 0;
747         unsigned long flags;
748
749         TRACE_ENTRY();
750
751         spin_lock_irqsave(&tgt->tgt_lock, flags);
752         tgt->retry_cmds++;
753         smp_mb();
754         TRACE(TRACE_RETRY, "TGT QUEUE FULL: incrementing retry_cmds %d",
755               tgt->retry_cmds);
756         if (finished_cmds != atomic_read(&tgt->finished_cmds)) {
757                 /* At least one cmd finished, so try again */
758                 tgt->retry_cmds--;
759                 TRACE(TRACE_RETRY, "Some command(s) finished, direct retry "
760                       "(finished_cmds=%d, tgt->finished_cmds=%d, "
761                       "retry_cmds=%d)", finished_cmds,
762                       atomic_read(&tgt->finished_cmds), tgt->retry_cmds);
763                 res = -1;
764                 goto out_unlock_tgt;
765         }
766
767         TRACE(TRACE_RETRY, "Adding cmd %p to retry cmd list", cmd);
768         list_add_tail(&cmd->cmd_list_entry, &tgt->retry_cmd_list);
769
770         if (!tgt->retry_timer_active) {
771                 tgt->retry_timer.expires = jiffies + SCST_TGT_RETRY_TIMEOUT;
772                 add_timer(&tgt->retry_timer);
773                 tgt->retry_timer_active = 1;
774         }
775
776 out_unlock_tgt:
777         spin_unlock_irqrestore(&tgt->tgt_lock, flags);
778
779         TRACE_EXIT_RES(res);
780         return res;
781 }
782
783 static int scst_rdy_to_xfer(struct scst_cmd *cmd)
784 {
785         int res, rc;
786         int atomic = scst_cmd_atomic(cmd);
787
788         TRACE_ENTRY();
789
790         if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
791                 TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
792                 goto out_dev_done;
793         }
794
795         if (cmd->tgtt->rdy_to_xfer == NULL) {
796                 cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
797                 res = SCST_CMD_STATE_RES_CONT_SAME;
798                 goto out;
799         }
800
801         if (atomic && !cmd->tgtt->rdy_to_xfer_atomic) {
802                 TRACE_DBG("%s", "rdy_to_xfer() can not be "
803                       "called in atomic context, rescheduling to the thread");
804                 res = SCST_CMD_STATE_RES_NEED_THREAD;
805                 goto out;
806         }
807
808         while (1) {
809                 int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds);
810
811                 res = SCST_CMD_STATE_RES_CONT_NEXT;
812                 cmd->state = SCST_CMD_STATE_DATA_WAIT;
813
814                 TRACE_DBG("Calling rdy_to_xfer(%p)", cmd);
815 #ifdef DEBUG_RETRY
816                 if (((scst_random() % 100) == 75))
817                         rc = SCST_TGT_RES_QUEUE_FULL;
818                 else
819 #endif
820                         rc = cmd->tgtt->rdy_to_xfer(cmd);
821                 TRACE_DBG("rdy_to_xfer() returned %d", rc);
822
823                 if (likely(rc == SCST_TGT_RES_SUCCESS))
824                         goto out;
825
826                 /* Restore the previous state */
827                 cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
828
829                 switch (rc) {
830                 case SCST_TGT_RES_QUEUE_FULL:
831                         if (scst_queue_retry_cmd(cmd, finished_cmds) == 0)
832                                 break;
833                         else
834                                 continue;
835
836                 case SCST_TGT_RES_NEED_THREAD_CTX:
837                         TRACE_DBG("Target driver %s "
838                               "rdy_to_xfer() requested thread "
839                               "context, rescheduling", cmd->tgtt->name);
840                         res = SCST_CMD_STATE_RES_NEED_THREAD;
841                         break;
842
843                 default:
844                         goto out_error_rc;
845                 }
846                 break;
847         }
848
849 out:
850         TRACE_EXIT_HRES(res);
851         return res;
852
853 out_error_rc:
854         if (rc == SCST_TGT_RES_FATAL_ERROR) {
855                 PRINT_ERROR("Target driver %s rdy_to_xfer() returned "
856                      "fatal error", cmd->tgtt->name);
857         } else {
858                 PRINT_ERROR("Target driver %s rdy_to_xfer() returned invalid "
859                             "value %d", cmd->tgtt->name, rc);
860         }
861         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
862
863 out_dev_done:
864         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
865         res = SCST_CMD_STATE_RES_CONT_SAME;
866         goto out;
867 }
868
869 /* No locks, but might be in IRQ */
870 void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
871         int check_retries)
872 {
873         unsigned long flags;
874
875         TRACE_ENTRY();
876
877         TRACE_DBG("Context: %d", context);
878
879         switch(context) {
880         case SCST_CONTEXT_DIRECT:
881         case SCST_CONTEXT_DIRECT_ATOMIC:
882                 if (check_retries)
883                         scst_check_retries(cmd->tgt);
884                 scst_process_active_cmd(cmd, context);
885                 break;
886
887         default:
888                 PRINT_ERROR("Context %x is unknown, using the thread one",
889                             context);
890                 /* go through */
891         case SCST_CONTEXT_THREAD:
892                 if (check_retries)
893                         scst_check_retries(cmd->tgt);
894                 spin_lock_irqsave(&cmd->cmd_lists->cmd_list_lock, flags);
895                 TRACE_DBG("Adding cmd %p to active cmd list", cmd);
896                 if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
897                         list_add(&cmd->cmd_list_entry,
898                                 &cmd->cmd_lists->active_cmd_list);
899                 else
900                         list_add_tail(&cmd->cmd_list_entry,
901                                 &cmd->cmd_lists->active_cmd_list);
902                 wake_up(&cmd->cmd_lists->cmd_list_waitQ);
903                 spin_unlock_irqrestore(&cmd->cmd_lists->cmd_list_lock, flags);
904                 break;
905
906         case SCST_CONTEXT_TASKLET:
907                 if (check_retries)
908                         scst_check_retries(cmd->tgt);
909                 scst_schedule_tasklet(cmd);
910                 break;
911         }
912
913         TRACE_EXIT();
914         return;
915 }
916
917 void scst_rx_data(struct scst_cmd *cmd, int status, int pref_context)
918 {
919         TRACE_ENTRY();
920
921         TRACE_DBG("Preferred context: %d", pref_context);
922         TRACE(TRACE_SCSI, "tag=%llu status=%#x", scst_cmd_get_tag(cmd), status);
923
924 #ifdef EXTRACHECKS
925         if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) ||
926                          (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)))
927         {
928                 PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
929                         "SCST_CONTEXT_TASKLET instead\n", pref_context,
930                         cmd->tgtt->name);
931                 pref_context = SCST_CONTEXT_TASKLET;
932         }
933 #endif
934
935         switch (status) {
936         case SCST_RX_STATUS_SUCCESS:
937                 cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
938                 /* Small context optimization */
939                 if ((pref_context == SCST_CONTEXT_TASKLET) || 
940                     (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)) {
941                         if ( !test_bit(SCST_TGT_DEV_AFTER_RX_DATA_ATOMIC, 
942                                         &cmd->tgt_dev->tgt_dev_flags))
943                                 pref_context = SCST_CONTEXT_THREAD;
944                 }
945                 break;
946
947         case SCST_RX_STATUS_ERROR_SENSE_SET:
948                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
949                 break;
950
951         case SCST_RX_STATUS_ERROR_FATAL:
952                 set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
953                 /* go through */
954         case SCST_RX_STATUS_ERROR:
955                 scst_set_cmd_error(cmd,
956                            SCST_LOAD_SENSE(scst_sense_hardw_error));
957                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
958                 break;
959
960         default:
961                 PRINT_ERROR("scst_rx_data() received unknown status %x",
962                         status);
963                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
964                 break;
965         }
966
967         scst_proccess_redirect_cmd(cmd, pref_context, 1);
968
969         TRACE_EXIT();
970         return;
971 }
972
973 static int scst_tgt_pre_exec(struct scst_cmd *cmd)
974 {
975         int res = SCST_CMD_STATE_RES_CONT_SAME, rc;
976
977         TRACE_ENTRY();
978
979         cmd->state = SCST_CMD_STATE_SEND_TO_MIDLEV;
980
981         if (cmd->tgtt->pre_exec == NULL)
982                 goto out;
983
984         TRACE_DBG("Calling pre_exec(%p)", cmd);
985         rc = cmd->tgtt->pre_exec(cmd);
986         TRACE_DBG("pre_exec() returned %d", rc);
987
988         if (unlikely(rc != SCST_PREPROCESS_STATUS_SUCCESS)) {
989                 switch(rc) {
990                 case SCST_PREPROCESS_STATUS_ERROR_SENSE_SET:
991                         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
992                         break;
993                 case SCST_PREPROCESS_STATUS_ERROR_FATAL:
994                         set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
995                         /* go through */
996                 case SCST_PREPROCESS_STATUS_ERROR:
997                         scst_set_cmd_error(cmd,
998                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
999                         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
1000                         break;
1001                 case SCST_PREPROCESS_STATUS_NEED_THREAD:
1002                         TRACE_DBG("Target driver's %s pre_exec() requested "
1003                                 "thread context, rescheduling", cmd->tgtt->name);
1004                         res = SCST_CMD_STATE_RES_NEED_THREAD;
1005                         cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
1006                         break;
1007                 default:
1008                         sBUG();
1009                         break;
1010                 }
1011         }
1012
1013 out:
1014         TRACE_EXIT_RES(res);
1015         return res;
1016 }
1017
1018 static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
1019         const uint8_t *rq_sense, int rq_sense_len, int resid)
1020 {
1021         TRACE_ENTRY();
1022
1023         cmd->status = result & 0xff;
1024         cmd->msg_status = msg_byte(result);
1025         cmd->host_status = host_byte(result);
1026         cmd->driver_status = driver_byte(result);
1027         if (unlikely(resid != 0)) {
1028 #ifdef EXTRACHECKS
1029                 if ((resid < 0) || (resid > cmd->resp_data_len)) {
1030                         PRINT_ERROR("Wrong resid %d (cmd->resp_data_len=%d, "
1031                                 "op %x)", resid, cmd->resp_data_len,
1032                                 cmd->cdb[0]);
1033                 } else
1034 #endif
1035                         scst_set_resp_data_len(cmd, cmd->resp_data_len - resid);
1036         }
1037
1038         /* 
1039          * We checked that rq_sense_len < sizeof(cmd->sense_buffer)
1040          * in init_scst()
1041          */
1042         memcpy(cmd->sense_buffer, rq_sense, rq_sense_len);
1043         memset(&cmd->sense_buffer[rq_sense_len], 0,
1044                 sizeof(cmd->sense_buffer) - rq_sense_len);
1045
1046         TRACE(TRACE_SCSI, "result=%x, cmd->status=%x, resid=%d, "
1047               "cmd->msg_status=%x, cmd->host_status=%x, "
1048               "cmd->driver_status=%x", result, cmd->status, resid,
1049               cmd->msg_status, cmd->host_status, cmd->driver_status);
1050
1051         cmd->completed = 1;
1052
1053         TRACE_EXIT();
1054         return;
1055 }
1056
1057 /* For small context optimization */
1058 static inline int scst_optimize_post_exec_context(struct scst_cmd *cmd,
1059         int context)
1060 {
1061         if ((context == SCST_CONTEXT_TASKLET) || 
1062             (context == SCST_CONTEXT_DIRECT_ATOMIC)) {
1063                 if ( !test_bit(SCST_TGT_DEV_AFTER_EXEC_ATOMIC, 
1064                                 &cmd->tgt_dev->tgt_dev_flags))
1065                         context = SCST_CONTEXT_THREAD;
1066         }
1067         return context;
1068 }
1069
1070 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
1071 static inline struct scst_cmd *scst_get_cmd(struct scsi_cmnd *scsi_cmd,
1072                                             struct scsi_request **req)
1073 {
1074         struct scst_cmd *cmd = NULL;
1075
1076         if (scsi_cmd && (*req = scsi_cmd->sc_request))
1077                 cmd = (struct scst_cmd *)(*req)->upper_private_data;
1078
1079         if (cmd == NULL) {
1080                 PRINT_ERROR("%s", "Request with NULL cmd");
1081                 if (*req)
1082                         scsi_release_request(*req);
1083         }
1084
1085         return cmd;
1086 }
1087
1088 static void scst_cmd_done(struct scsi_cmnd *scsi_cmd)
1089 {
1090         struct scsi_request *req = NULL;
1091         struct scst_cmd *cmd;
1092
1093         TRACE_ENTRY();
1094
1095         cmd = scst_get_cmd(scsi_cmd, &req);
1096         if (cmd == NULL)
1097                 goto out;
1098
1099         scst_do_cmd_done(cmd, req->sr_result, req->sr_sense_buffer,
1100                 sizeof(req->sr_sense_buffer), scsi_cmd->resid);
1101
1102         /* Clear out request structure */
1103         req->sr_use_sg = 0;
1104         req->sr_sglist_len = 0;
1105         req->sr_bufflen = 0;
1106         req->sr_buffer = NULL;
1107         req->sr_underflow = 0;
1108         req->sr_request->rq_disk = NULL; /* disown request blk */
1109
1110         scst_release_request(cmd);
1111
1112         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
1113
1114         scst_proccess_redirect_cmd(cmd,
1115                 scst_optimize_post_exec_context(cmd, scst_get_context()), 0);
1116
1117 out:
1118         TRACE_EXIT();
1119         return;
1120 }
1121 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */
1122 static void scst_cmd_done(void *data, char *sense, int result, int resid)
1123 {
1124         struct scst_cmd *cmd;
1125
1126         TRACE_ENTRY();
1127
1128         cmd = (struct scst_cmd *)data;
1129         if (cmd == NULL)
1130                 goto out;
1131
1132         scst_do_cmd_done(cmd, result, sense, SCST_SENSE_BUFFERSIZE, resid);
1133
1134         cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
1135
1136         scst_proccess_redirect_cmd(cmd,
1137                 scst_optimize_post_exec_context(cmd, scst_get_context()), 0);
1138
1139 out:
1140         TRACE_EXIT();
1141         return;
1142 }
1143 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */
1144
1145 static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state)
1146 {
1147         TRACE_ENTRY();
1148
1149         if (next_state == SCST_CMD_STATE_DEFAULT)
1150                 next_state = SCST_CMD_STATE_PRE_DEV_DONE;
1151
1152 #if defined(DEBUG) || defined(TRACING)
1153         if (next_state == SCST_CMD_STATE_PRE_DEV_DONE) {
1154                 if (cmd->sg) {
1155                         int i;
1156                         struct scatterlist *sg = cmd->sg;
1157                         TRACE(TRACE_RECV_TOP, 
1158                               "Exec'd %d S/G(s) at %p sg[0].page at %p",
1159                               cmd->sg_cnt, sg, (void*)sg[0].page);
1160                         for(i = 0; i < cmd->sg_cnt; ++i) {
1161                                 TRACE_BUFF_FLAG(TRACE_RECV_TOP, 
1162                                         "Exec'd sg", page_address(sg[i].page),
1163                                         sg[i].length);
1164                         }
1165                 }
1166         }
1167 #endif
1168
1169
1170 #ifdef EXTRACHECKS
1171         if ((next_state != SCST_CMD_STATE_PRE_DEV_DONE) &&
1172             (next_state != SCST_CMD_STATE_PRE_XMIT_RESP) &&
1173             (next_state != SCST_CMD_STATE_FINISHED)) 
1174         {
1175                 PRINT_ERROR("scst_cmd_done_local() received invalid cmd "
1176                             "state %d (opcode %d)", next_state, cmd->cdb[0]);
1177                 scst_set_cmd_error(cmd,
1178                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
1179                 next_state = SCST_CMD_STATE_PRE_DEV_DONE;
1180         }
1181 #endif
1182         cmd->state = next_state;
1183
1184         scst_proccess_redirect_cmd(cmd,
1185                 scst_optimize_post_exec_context(cmd, scst_get_context()), 0);
1186
1187         TRACE_EXIT();
1188         return;
1189 }
1190
1191 static int scst_report_luns_local(struct scst_cmd *cmd)
1192 {
1193         int rc;
1194         int dev_cnt = 0;
1195         int buffer_size;
1196         int i;
1197         struct scst_tgt_dev *tgt_dev = NULL;
1198         uint8_t *buffer;
1199         int offs, overflow = 0;
1200
1201         TRACE_ENTRY();
1202
1203         rc = scst_check_local_events(cmd);
1204         if (unlikely(rc != 0))
1205                 goto out_done;
1206
1207         cmd->status = 0;
1208         cmd->msg_status = 0;
1209         cmd->host_status = DID_OK;
1210         cmd->driver_status = 0;
1211
1212         if ((cmd->cdb[2] != 0) && (cmd->cdb[2] != 2)) {
1213                 PRINT_ERROR("Unsupported SELECT REPORT value %x in REPORT "
1214                         "LUNS command", cmd->cdb[2]);
1215                 goto out_err;
1216         }
1217
1218         buffer_size = scst_get_buf_first(cmd, &buffer);
1219         if (unlikely(buffer_size <= 0))
1220                 goto out_err;
1221
1222         if (buffer_size < 16)
1223                 goto out_put_err;
1224
1225         memset(buffer, 0, buffer_size);
1226         offs = 8;
1227
1228         /* sess->sess_tgt_dev_list_hash is protected by suspended activity */
1229         for(i = 0; i < TGT_DEV_HASH_SIZE; i++) {
1230                 struct list_head *sess_tgt_dev_list_head =
1231                         &cmd->sess->sess_tgt_dev_list_hash[i];
1232                 list_for_each_entry(tgt_dev, sess_tgt_dev_list_head,
1233                                 sess_tgt_dev_list_entry) {
1234                         if (!overflow) {
1235                                 if (offs >= buffer_size) {
1236                                         scst_put_buf(cmd, buffer);
1237                                         buffer_size = scst_get_buf_next(cmd, &buffer);
1238                                         if (buffer_size > 0) {
1239                                                 memset(buffer, 0, buffer_size);
1240                                                 offs = 0;
1241                                         } else {
1242                                                 overflow = 1;
1243                                                 goto inc_dev_cnt;
1244                                         }
1245                                 }
1246                                 if ((buffer_size - offs) < 8) {
1247                                         PRINT_ERROR("Buffer allocated for REPORT "
1248                                                 "LUNS command doesn't allow to fit 8 "
1249                                                 "byte entry (buffer_size=%d)",
1250                                                 buffer_size);
1251                                         goto out_put_hw_err;
1252                                 }
1253                                 buffer[offs] = (tgt_dev->lun >> 8) & 0xff;
1254                                 buffer[offs+1] = tgt_dev->lun & 0xff;
1255                                 offs += 8;
1256                         }
1257 inc_dev_cnt:
1258                         dev_cnt++;
1259                 }
1260         }
1261         if (!overflow)
1262                 scst_put_buf(cmd, buffer);
1263
1264         /* Set the response header */
1265         buffer_size = scst_get_buf_first(cmd, &buffer);
1266         if (unlikely(buffer_size <= 0))
1267                 goto out_err;
1268         dev_cnt *= 8;
1269         buffer[0] = (dev_cnt >> 24) & 0xff;
1270         buffer[1] = (dev_cnt >> 16) & 0xff;
1271         buffer[2] = (dev_cnt >> 8) & 0xff;
1272         buffer[3] = dev_cnt & 0xff;
1273         scst_put_buf(cmd, buffer);
1274
1275         dev_cnt += 8;
1276         if (dev_cnt < cmd->resp_data_len)
1277                 scst_set_resp_data_len(cmd, dev_cnt);
1278
1279 out_compl:
1280         cmd->completed = 1;
1281
1282 out_done:
1283         /* Report the result */
1284         scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT);
1285
1286         TRACE_EXIT();
1287         return SCST_EXEC_COMPLETED;
1288         
1289 out_put_err:
1290         scst_put_buf(cmd, buffer);
1291
1292 out_err:
1293         scst_set_cmd_error(cmd,
1294                    SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1295         goto out_compl;
1296
1297 out_put_hw_err:
1298         scst_put_buf(cmd, buffer);
1299         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
1300         goto out_compl;
1301 }
1302
1303 static int scst_pre_select(struct scst_cmd *cmd)
1304 {
1305         int res = SCST_EXEC_NOT_COMPLETED;
1306
1307         TRACE_ENTRY();
1308
1309         if (scst_cmd_atomic(cmd)) {
1310                 res = SCST_EXEC_NEED_THREAD;
1311                 goto out;
1312         }
1313
1314         if (cmd->local_exec_done)
1315                 goto out;
1316
1317         cmd->local_exec_done = 1;
1318
1319         scst_block_dev_cmd(cmd, 1);
1320
1321         /* Check for local events will be done when cmd will be executed */
1322
1323 out:
1324         TRACE_EXIT_RES(res);
1325         return res;
1326 }
1327
1328 static int scst_reserve_local(struct scst_cmd *cmd)
1329 {
1330         int res = SCST_EXEC_NOT_COMPLETED, rc;
1331         struct scst_device *dev;
1332         struct scst_tgt_dev *tgt_dev_tmp;
1333
1334         TRACE_ENTRY();
1335
1336         if (scst_cmd_atomic(cmd)) {
1337                 res = SCST_EXEC_NEED_THREAD;
1338                 goto out;
1339         }
1340
1341         if (cmd->local_exec_done)
1342                 goto out;
1343
1344         cmd->local_exec_done = 1;
1345
1346         if ((cmd->cdb[0] == RESERVE_10) && (cmd->cdb[2] & SCST_RES_3RDPTY)) {
1347                 PRINT_ERROR("RESERVE_10: 3rdPty RESERVE not implemented "
1348                      "(lun=%Ld)", (uint64_t)cmd->lun);
1349                 scst_set_cmd_error(cmd,
1350                         SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1351                 goto out_done;
1352         }
1353
1354         dev = cmd->dev;
1355
1356         scst_block_dev_cmd(cmd, 1);
1357
1358         rc = scst_check_local_events(cmd);
1359         if (unlikely(rc != 0))
1360                 goto out_done;
1361
1362         spin_lock_bh(&dev->dev_lock);
1363
1364         if (test_bit(SCST_TGT_DEV_RESERVED, &cmd->tgt_dev->tgt_dev_flags)) {
1365                 spin_unlock_bh(&dev->dev_lock);
1366                 scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
1367                 goto out_done;
1368         }
1369
1370         list_for_each_entry(tgt_dev_tmp, &dev->dev_tgt_dev_list,
1371                             dev_tgt_dev_list_entry) {
1372                 if (cmd->tgt_dev != tgt_dev_tmp)
1373                         set_bit(SCST_TGT_DEV_RESERVED, 
1374                                 &tgt_dev_tmp->tgt_dev_flags);
1375         }
1376         dev->dev_reserved = 1;
1377
1378         spin_unlock_bh(&dev->dev_lock);
1379         
1380 out:
1381         TRACE_EXIT_RES(res);
1382         return res;
1383
1384 out_done:
1385         /* Report the result */
1386         scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT);
1387         res = SCST_EXEC_COMPLETED;
1388         goto out;
1389 }
1390
1391 static int scst_release_local(struct scst_cmd *cmd)
1392 {
1393         int res = SCST_EXEC_NOT_COMPLETED, rc;
1394         struct scst_tgt_dev *tgt_dev_tmp;
1395         struct scst_device *dev;
1396
1397         TRACE_ENTRY();
1398
1399         if (scst_cmd_atomic(cmd)) {
1400                 res = SCST_EXEC_NEED_THREAD;
1401                 goto out;
1402         }
1403
1404         if (cmd->local_exec_done)
1405                 goto out;
1406
1407         cmd->local_exec_done = 1;
1408
1409         dev = cmd->dev;
1410
1411         scst_block_dev_cmd(cmd, 1);
1412
1413         rc = scst_check_local_events(cmd);
1414         if (unlikely(rc != 0))
1415                 goto out_done;
1416
1417         spin_lock_bh(&dev->dev_lock);
1418
1419         /* 
1420          * The device could be RELEASED behind us, if RESERVING session 
1421          * is closed (see scst_free_tgt_dev()), but this actually doesn't 
1422          * matter, so use lock and no retest for DEV_RESERVED bits again
1423          */
1424         if (test_bit(SCST_TGT_DEV_RESERVED, &cmd->tgt_dev->tgt_dev_flags)) {
1425                 res = SCST_EXEC_COMPLETED;
1426                 cmd->status = 0;
1427                 cmd->msg_status = 0;
1428                 cmd->host_status = DID_OK;
1429                 cmd->driver_status = 0;
1430                 cmd->completed = 1;
1431         } else {
1432                 list_for_each_entry(tgt_dev_tmp,
1433                                     &dev->dev_tgt_dev_list,
1434                                     dev_tgt_dev_list_entry) {
1435                         clear_bit(SCST_TGT_DEV_RESERVED, 
1436                                 &tgt_dev_tmp->tgt_dev_flags);
1437                 }
1438                 dev->dev_reserved = 0;
1439         }
1440
1441         spin_unlock_bh(&dev->dev_lock);
1442
1443         if (res == SCST_EXEC_COMPLETED)
1444                 goto out_done;
1445
1446 out:
1447         TRACE_EXIT_RES(res);
1448         return res;
1449
1450 out_done:
1451         res = SCST_EXEC_COMPLETED;
1452         /* Report the result */
1453         scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT);
1454         goto out;
1455 }
1456
1457 /* No locks, no IRQ or IRQ-safe context allowed */
1458 int scst_check_local_events(struct scst_cmd *cmd)
1459 {
1460         int res, rc;
1461         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
1462
1463         TRACE_ENTRY();
1464
1465         if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
1466                 TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
1467                 goto out_uncomplete;
1468         }
1469
1470         /* Reserve check before Unit Attention */
1471         if (unlikely(test_bit(SCST_TGT_DEV_RESERVED, &tgt_dev->tgt_dev_flags))) {
1472                 if ((cmd->cdb[0] != INQUIRY) && (cmd->cdb[0] != REPORT_LUNS) &&
1473                     (cmd->cdb[0] != RELEASE) && (cmd->cdb[0] != RELEASE_10) &&
1474                     (cmd->cdb[0] != REPORT_DEVICE_IDENTIFIER) &&
1475                     (cmd->cdb[0] != ALLOW_MEDIUM_REMOVAL || (cmd->cdb[4] & 3)) &&
1476                     (cmd->cdb[0] != LOG_SENSE) && (cmd->cdb[0] != REQUEST_SENSE)) {
1477                         scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
1478                         goto out_complete;
1479                 }
1480         }
1481
1482         /* If we had internal bus reset, set the command error unit attention */
1483         if ((cmd->dev->scsi_dev != NULL) &&
1484             unlikely(cmd->dev->scsi_dev->was_reset)) {
1485                 if (scst_is_ua_command(cmd)) {
1486                         struct scst_device *dev = cmd->dev;
1487                         int done = 0;
1488                         /* Prevent more than 1 cmd to be triggered by was_reset */
1489                         spin_lock_bh(&dev->dev_lock);
1490                         barrier(); /* to reread was_reset */
1491                         if (dev->scsi_dev->was_reset) {
1492                                 TRACE(TRACE_MGMT, "was_reset is %d", 1);
1493                                 scst_set_cmd_error(cmd,
1494                                            SCST_LOAD_SENSE(scst_sense_reset_UA));
1495                                 /* It looks like it is safe to clear was_reset here */
1496                                 dev->scsi_dev->was_reset = 0;
1497                                 smp_mb();
1498                                 done = 1;
1499                         }
1500                         spin_unlock_bh(&dev->dev_lock);
1501
1502                         if (done)
1503                                 goto out_complete;
1504                 }
1505         }
1506
1507         if (unlikely(test_bit(SCST_TGT_DEV_UA_PENDING, 
1508                         &cmd->tgt_dev->tgt_dev_flags))) {
1509                 if (scst_is_ua_command(cmd)) {
1510                         rc = scst_set_pending_UA(cmd);
1511                         if (rc == 0)
1512                                 goto out_complete;
1513                 }
1514         }
1515
1516         res = 0;
1517
1518 out:
1519         TRACE_EXIT_RES(res);
1520         return res;
1521
1522 out_complete:
1523         res = 1;
1524         sBUG_ON(!cmd->completed);
1525         goto out;
1526
1527 out_uncomplete:
1528         res = -1;
1529         goto out;
1530 }
1531
1532 /* 
1533  * The result of cmd execution, if any, should be reported 
1534  * via scst_cmd_done_local() 
1535  */
1536 static int scst_pre_exec(struct scst_cmd *cmd)
1537 {
1538         int res = SCST_EXEC_NOT_COMPLETED;
1539         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
1540
1541         TRACE_ENTRY();
1542
1543         /*
1544          * This function can be called several times for the same cmd, so it
1545          * can't change any state in a non-reentrable way or use something
1546          * like local_exec_done!!
1547          */
1548
1549         /* Check READ_ONLY device status */
1550         if (((tgt_dev->acg_dev->rd_only_flag) || cmd->dev->swp) &&
1551             (cmd->cdb[0] == WRITE_6 ||  /* ToDo: full list of the modify cmds */
1552              cmd->cdb[0] == WRITE_10 ||
1553              cmd->cdb[0] == WRITE_12 ||
1554              cmd->cdb[0] == WRITE_16 ||
1555              cmd->cdb[0] == WRITE_VERIFY ||
1556              cmd->cdb[0] == WRITE_VERIFY_12 ||
1557              cmd->cdb[0] == WRITE_VERIFY_16 ||
1558              (cmd->dev->handler->type == TYPE_TAPE &&
1559               (cmd->cdb[0] == ERASE || cmd->cdb[0] == WRITE_FILEMARKS)))) {
1560                 scst_set_cmd_error(cmd,
1561                            SCST_LOAD_SENSE(scst_sense_data_protect));
1562                 goto out_done;
1563         }
1564
1565 out:
1566         TRACE_EXIT_RES(res);
1567         return res;
1568
1569 out_done:
1570         res = SCST_EXEC_COMPLETED;
1571         /* Report the result */
1572         scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT);
1573         goto out;
1574 }
1575
1576 /* 
1577  * The result of cmd execution, if any, should be reported 
1578  * via scst_cmd_done_local() 
1579  */
1580 static inline int scst_local_exec(struct scst_cmd *cmd)
1581 {
1582         int res = SCST_EXEC_NOT_COMPLETED;
1583
1584         TRACE_ENTRY();
1585
1586         /*
1587          * Adding new commands here don't forget to update
1588          * scst_is_cmd_local() in scsi_tgt.h, if necessary
1589          */
1590
1591         switch (cmd->cdb[0]) {
1592         case MODE_SELECT:
1593         case MODE_SELECT_10:
1594         case LOG_SELECT:
1595                 res = scst_pre_select(cmd);
1596                 break;
1597         case RESERVE:
1598         case RESERVE_10:
1599                 res = scst_reserve_local(cmd);
1600                 break;
1601         case RELEASE:
1602         case RELEASE_10:
1603                 res = scst_release_local(cmd);
1604                 break;
1605         case REPORT_LUNS:
1606                 res = scst_report_luns_local(cmd);
1607                 break;
1608         }
1609
1610         TRACE_EXIT_RES(res);
1611         return res;
1612 }
1613
1614 static int scst_do_send_to_midlev(struct scst_cmd *cmd)
1615 {
1616         int rc = SCST_EXEC_NOT_COMPLETED;
1617
1618         TRACE_ENTRY();
1619
1620         /* Check here to let an out of SN cmd be queued w/o context switch */
1621         if (scst_cmd_atomic(cmd) && !cmd->dev->handler->exec_atomic) {
1622                 TRACE_DBG("Dev handler %s exec() can not be "
1623                       "called in atomic context, rescheduling to the thread",
1624                       cmd->dev->handler->name);
1625                 rc = SCST_EXEC_NEED_THREAD;
1626                 goto out;
1627         }
1628
1629         cmd->sent_to_midlev = 1;
1630         cmd->state = SCST_CMD_STATE_EXECUTING;
1631         cmd->scst_cmd_done = scst_cmd_done_local;
1632
1633         rc = scst_pre_exec(cmd);
1634         /* !! At this point cmd, sess & tgt_dev can be already freed !! */
1635         if (rc != SCST_EXEC_NOT_COMPLETED) {
1636                 if (rc == SCST_EXEC_COMPLETED)
1637                         goto out;
1638                 else if (rc == SCST_EXEC_NEED_THREAD)
1639                         goto out_clear;
1640                 else
1641                         goto out_rc_error;
1642         }
1643
1644         rc = scst_local_exec(cmd);
1645         /* !! At this point cmd, sess & tgt_dev can be already freed !! */
1646         if (rc != SCST_EXEC_NOT_COMPLETED) {
1647                 if (rc == SCST_EXEC_COMPLETED)
1648                         goto out;
1649                 else if (rc == SCST_EXEC_NEED_THREAD)
1650                         goto out_clear;
1651                 else
1652                         goto out_rc_error;
1653         }
1654
1655         if (cmd->dev->handler->exec) {
1656                 struct scst_device *dev = cmd->dev;
1657                 TRACE_DBG("Calling dev handler %s exec(%p)",
1658                       dev->handler->name, cmd);
1659                 TRACE_BUFF_FLAG(TRACE_SEND_TOP, "Execing: ", cmd->cdb, cmd->cdb_len);
1660                 cmd->scst_cmd_done = scst_cmd_done_local;
1661                 rc = dev->handler->exec(cmd);
1662                 /* !! At this point cmd, sess & tgt_dev can be already freed !! */
1663                 TRACE_DBG("Dev handler %s exec() returned %d",
1664                       dev->handler->name, rc);
1665                 if (rc == SCST_EXEC_COMPLETED)
1666                         goto out;
1667                 else if (rc == SCST_EXEC_NEED_THREAD)
1668                         goto out_clear;
1669                 else if (rc != SCST_EXEC_NOT_COMPLETED)
1670                         goto out_rc_error;
1671         }
1672
1673         TRACE_DBG("Sending cmd %p to SCSI mid-level", cmd);
1674         
1675         if (unlikely(cmd->dev->scsi_dev == NULL)) {
1676                 PRINT_ERROR("Command for virtual device must be "
1677                         "processed by device handler (lun %Ld)!",
1678                         (uint64_t)cmd->lun);
1679                 goto out_error;
1680         }
1681
1682         rc = scst_check_local_events(cmd);
1683         if (unlikely(rc != 0))
1684                 goto out_done;
1685
1686 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) 
1687         if (unlikely(scst_alloc_request(cmd) != 0)) {
1688                 if (scst_cmd_atomic(cmd)) {
1689                         rc = SCST_EXEC_NEED_THREAD;
1690                         goto out_clear;
1691                 } else {
1692                         PRINT_INFO("%s", "Unable to allocate request, "
1693                                 "sending BUSY status");
1694                         goto out_busy;
1695                 }
1696         }
1697         
1698         scst_do_req(cmd->scsi_req, (void *)cmd->cdb,
1699                     (void *)cmd->scsi_req->sr_buffer,
1700                     cmd->scsi_req->sr_bufflen, scst_cmd_done, cmd->timeout,
1701                     cmd->retries);
1702 #else
1703         rc = scst_exec_req(cmd->dev->scsi_dev, cmd->cdb, cmd->cdb_len,
1704                         cmd->data_direction, cmd->sg, cmd->bufflen, cmd->sg_cnt,
1705                         cmd->timeout, cmd->retries, cmd, scst_cmd_done,
1706                         scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1707         if (unlikely(rc != 0)) {
1708                 if (scst_cmd_atomic(cmd)) {
1709                         rc = SCST_EXEC_NEED_THREAD;
1710                         goto out_clear;
1711                 } else {
1712                         PRINT_INFO("scst_exec_req() failed: %d", rc);
1713                         goto out_error;
1714                 }
1715         }
1716 #endif
1717
1718         rc = SCST_EXEC_COMPLETED;
1719
1720 out:
1721         TRACE_EXIT();
1722         return rc;
1723
1724 out_clear:
1725         /* Restore the state */
1726         cmd->sent_to_midlev = 0;
1727         cmd->state = SCST_CMD_STATE_SEND_TO_MIDLEV;
1728         goto out;
1729
1730 out_rc_error:
1731         PRINT_ERROR("Dev handler %s exec() or scst_local_exec() returned "
1732                     "invalid code %d", cmd->dev->handler->name, rc);
1733         /* go through */
1734
1735 out_error:
1736         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
1737
1738 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) 
1739 out_busy:
1740         scst_set_busy(cmd);
1741         /* go through */
1742 #endif
1743
1744 out_done:
1745         rc = SCST_EXEC_COMPLETED;
1746         /* Report the result */
1747         scst_cmd_done_local(cmd, SCST_CMD_STATE_DEFAULT);
1748         goto out;
1749 }
1750
1751 /* No locks */
1752 void scst_inc_expected_sn(struct scst_tgt_dev *tgt_dev, atomic_t *slot)
1753 {
1754         if (slot == NULL)
1755                 goto inc;
1756
1757         /* Optimized for lockless fast path */
1758
1759         TRACE_SN("Slot %zd, *cur_sn_slot %d", slot - tgt_dev->sn_slots,
1760                 atomic_read(slot));
1761
1762         if (!atomic_dec_and_test(slot))
1763                 goto out;
1764
1765         TRACE_SN("Slot is 0 (num_free_sn_slots=%d)",
1766                 tgt_dev->num_free_sn_slots);
1767         if (tgt_dev->num_free_sn_slots != ARRAY_SIZE(tgt_dev->sn_slots)) {
1768                 spin_lock_irq(&tgt_dev->sn_lock);
1769                 if (tgt_dev->num_free_sn_slots != ARRAY_SIZE(tgt_dev->sn_slots)) {
1770                         tgt_dev->num_free_sn_slots++;
1771                         TRACE_SN("Incremented num_free_sn_slots (%d)",
1772                                 tgt_dev->num_free_sn_slots);
1773                         if (tgt_dev->num_free_sn_slots == 0)
1774                                 tgt_dev->cur_sn_slot = slot;
1775                 }
1776                 spin_unlock_irq(&tgt_dev->sn_lock);
1777         }
1778
1779 inc:
1780         /*
1781          * No locks is needed, because only one thread at time can 
1782          * be here (serialized by sn). Also it is supposed that there
1783          * could not be half-incremented halves.
1784          */
1785         tgt_dev->expected_sn++;
1786         smp_mb(); /* write must be before def_cmd_count read */
1787         TRACE_SN("Next expected_sn: %ld", tgt_dev->expected_sn);
1788
1789 out:
1790         return;
1791 }
1792
1793 static int scst_send_to_midlev(struct scst_cmd **active_cmd)
1794 {
1795         int res, rc;
1796         struct scst_cmd *cmd = *active_cmd;
1797         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
1798         struct scst_device *dev = cmd->dev;
1799         typeof(tgt_dev->expected_sn) expected_sn;
1800         int count;
1801
1802         TRACE_ENTRY();
1803
1804         res = SCST_CMD_STATE_RES_CONT_NEXT;
1805
1806         __scst_get(0); /* protect dev & tgt_dev */
1807
1808         if (unlikely(cmd->internal || cmd->retry)) {
1809                 rc = scst_do_send_to_midlev(cmd);
1810                 /* !! At this point cmd, sess & tgt_dev can be already freed !! */
1811                 if (rc == SCST_EXEC_NEED_THREAD) {
1812                         TRACE_DBG("%s", "scst_do_send_to_midlev() requested "
1813                               "thread context, rescheduling");
1814                         res = SCST_CMD_STATE_RES_NEED_THREAD;
1815                         scst_dec_on_dev_cmd(cmd);
1816                         goto out_put;
1817                 } else {
1818                         sBUG_ON(rc != SCST_EXEC_COMPLETED);
1819                         goto out_unplug;
1820                 }
1821         }
1822
1823         if (unlikely(scst_inc_on_dev_cmd(cmd) != 0))
1824                 goto out_put;
1825
1826         if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
1827                 goto exec;
1828
1829         sBUG_ON(!cmd->sn_set);
1830
1831         expected_sn = tgt_dev->expected_sn;
1832         /* Optimized for lockless fast path */
1833         if ((cmd->sn != expected_sn) || (tgt_dev->hq_cmd_count > 0)) {
1834                 spin_lock_irq(&tgt_dev->sn_lock);
1835                 tgt_dev->def_cmd_count++;
1836                 smp_mb();
1837                 barrier(); /* to reread expected_sn & hq_cmd_count */
1838                 expected_sn = tgt_dev->expected_sn;
1839                 if ((cmd->sn != expected_sn) || (tgt_dev->hq_cmd_count > 0)) {
1840                         /* We are under IRQ lock, but dev->dev_lock is BH one */
1841                         int cmd_blocking = scst_pre_dec_on_dev_cmd(cmd);
1842                         if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
1843                                 /* Necessary to allow aborting out of sn cmds */
1844                                 TRACE_MGMT_DBG("Aborting out of sn cmd %p (tag %llu)",
1845                                         cmd, cmd->tag);
1846                                 tgt_dev->def_cmd_count--;
1847                                 cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
1848                                 res = SCST_CMD_STATE_RES_CONT_SAME;
1849                         } else {
1850                                 TRACE_SN("Deferring cmd %p (sn=%ld, set %d, "
1851                                         "expected_sn=%ld)", cmd, cmd->sn,
1852                                         cmd->sn_set, expected_sn);
1853                                 list_add_tail(&cmd->sn_cmd_list_entry,
1854                                               &tgt_dev->deferred_cmd_list);
1855                         }
1856                         spin_unlock_irq(&tgt_dev->sn_lock);
1857                         /* !! At this point cmd can be already freed !! */
1858                         __scst_dec_on_dev_cmd(dev, cmd_blocking);
1859                         goto out_put;
1860                 } else {
1861                         TRACE_SN("Somebody incremented expected_sn %ld, "
1862                                 "continuing", expected_sn);
1863                         tgt_dev->def_cmd_count--;
1864                         spin_unlock_irq(&tgt_dev->sn_lock);
1865                 }
1866         }
1867
1868 exec:
1869         count = 0;
1870         while(1) {
1871                 atomic_t *slot = cmd->sn_slot;
1872                 int inc_expected_sn = !cmd->inc_expected_sn_on_done &&
1873                                       cmd->sn_set;
1874                 rc = scst_do_send_to_midlev(cmd);
1875                 if (rc == SCST_EXEC_NEED_THREAD) {
1876                         TRACE_DBG("%s", "scst_do_send_to_midlev() requested "
1877                               "thread context, rescheduling");
1878                         res = SCST_CMD_STATE_RES_NEED_THREAD;
1879                         scst_dec_on_dev_cmd(cmd);
1880                         *active_cmd = cmd;
1881                         if (count != 0)
1882                                 goto out_unplug;
1883                         else
1884                                 goto out_put;
1885                 }
1886                 sBUG_ON(rc != SCST_EXEC_COMPLETED);
1887                 /* !! At this point cmd can be already freed !! */
1888                 count++;
1889                 if (inc_expected_sn)
1890                         scst_inc_expected_sn(tgt_dev, slot);
1891                 cmd = scst_check_deferred_commands(tgt_dev);
1892                 if (cmd == NULL)
1893                         break;
1894                 if (unlikely(scst_inc_on_dev_cmd(cmd) != 0))
1895                         break;
1896         }
1897
1898 out_unplug:
1899         if (dev->scsi_dev != NULL)
1900                 generic_unplug_device(dev->scsi_dev->request_queue);
1901
1902 out_put:
1903         __scst_put();
1904         /* !! At this point sess, dev and tgt_dev can be already freed !! */
1905
1906         TRACE_EXIT_HRES(res);
1907         return res;
1908 }
1909
1910 /* No locks supposed to be held */
1911 static int scst_check_sense(struct scst_cmd *cmd)
1912 {
1913         int res = 0;
1914         struct scst_device *dev = cmd->dev;
1915         int dbl_ua_possible, ua_sent = 0;
1916
1917         TRACE_ENTRY();
1918
1919         /* If we had internal bus reset behind us, set the command error UA */
1920         if ((dev->scsi_dev != NULL) &&
1921             unlikely(cmd->host_status == DID_RESET) &&
1922             scst_is_ua_command(cmd)) {
1923                 TRACE(TRACE_MGMT, "DID_RESET: was_reset=%d host_status=%x",
1924                       dev->scsi_dev->was_reset, cmd->host_status);
1925                 scst_set_cmd_error(cmd,
1926                    SCST_LOAD_SENSE(scst_sense_reset_UA));
1927                 /* just in case */
1928                 cmd->ua_ignore = 0;
1929                 /* It looks like it is safe to clear was_reset here */
1930                 dev->scsi_dev->was_reset = 0;
1931                 smp_mb();
1932         }
1933
1934         dbl_ua_possible = dev->dev_double_ua_possible;
1935         TRACE_DBG("cmd %p dbl_ua_possible %d", cmd, dbl_ua_possible);
1936         if (unlikely(dbl_ua_possible)) {
1937                 spin_lock_bh(&dev->dev_lock);
1938                 barrier(); /* to reread dev_double_ua_possible */
1939                 dbl_ua_possible = dev->dev_double_ua_possible;
1940                 if (dbl_ua_possible)
1941                         ua_sent = dev->dev_reset_ua_sent;
1942                 else
1943                         spin_unlock_bh(&dev->dev_lock);
1944         }
1945
1946         if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) && 
1947             SCST_SENSE_VALID(cmd->sense_buffer)) {
1948                 TRACE_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer,
1949                         sizeof(cmd->sense_buffer));
1950                 /* Check Unit Attention Sense Key */
1951                 if (scst_is_ua_sense(cmd->sense_buffer)) {
1952                         if (cmd->sense_buffer[12] == SCST_SENSE_ASC_UA_RESET) {
1953                                 if (dbl_ua_possible) {
1954                                         if (ua_sent) {
1955                                                 TRACE(TRACE_MGMT_MINOR, "%s", 
1956                                                         "Double UA detected");
1957                                                 /* Do retry */
1958                                                 TRACE(TRACE_MGMT_MINOR, "Retrying cmd %p "
1959                                                         "(tag %llu)", cmd, cmd->tag);
1960                                                 cmd->status = 0;
1961                                                 cmd->msg_status = 0;
1962                                                 cmd->host_status = DID_OK;
1963                                                 cmd->driver_status = 0;
1964                                                 memset(cmd->sense_buffer, 0,
1965                                                         sizeof(cmd->sense_buffer));
1966                                                 cmd->retry = 1;
1967                                                 cmd->state = SCST_CMD_STATE_SEND_TO_MIDLEV;
1968                                                 res = 1;
1969                                                 /* 
1970                                                  * Dev is still blocked by this cmd, so
1971                                                  * it's OK to clear SCST_DEV_SERIALIZED
1972                                                  * here.
1973                                                  */
1974                                                 dev->dev_double_ua_possible = 0;
1975                                                 dev->dev_serialized = 0;
1976                                                 dev->dev_reset_ua_sent = 0;
1977                                                 goto out_unlock;
1978                                         } else
1979                                                 dev->dev_reset_ua_sent = 1;
1980                                 }
1981                         }
1982                         if (cmd->ua_ignore == 0) {
1983                                 if (unlikely(dbl_ua_possible)) {
1984                                         __scst_dev_check_set_UA(dev, cmd,
1985                                                 cmd->sense_buffer,
1986                                                 sizeof(cmd->sense_buffer));
1987                                 } else {
1988                                         scst_dev_check_set_UA(dev, cmd,
1989                                                 cmd->sense_buffer,
1990                                                 sizeof(cmd->sense_buffer));
1991                                 }
1992                         }
1993                 }
1994         }
1995
1996         if (unlikely(dbl_ua_possible)) {
1997                 if (ua_sent && scst_is_ua_command(cmd)) {
1998                         TRACE_MGMT_DBG("%s", "Clearing dbl_ua_possible flag");
1999                         dev->dev_double_ua_possible = 0;
2000                         dev->dev_serialized = 0;
2001                         dev->dev_reset_ua_sent = 0;
2002                 }
2003                 spin_unlock_bh(&dev->dev_lock);
2004         }
2005
2006 out:
2007         TRACE_EXIT_RES(res);
2008         return res;
2009
2010 out_unlock:
2011         spin_unlock_bh(&dev->dev_lock);
2012         goto out;
2013 }
2014
2015 static int scst_check_auto_sense(struct scst_cmd *cmd)
2016 {
2017         int res = 0;
2018
2019         TRACE_ENTRY();
2020
2021         if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) &&
2022             (!SCST_SENSE_VALID(cmd->sense_buffer) ||
2023              SCST_NO_SENSE(cmd->sense_buffer))) {
2024                 TRACE(TRACE_SCSI|TRACE_MINOR, "CHECK_CONDITION, but no sense: "
2025                       "cmd->status=%x, cmd->msg_status=%x, "
2026                       "cmd->host_status=%x, cmd->driver_status=%x", cmd->status,
2027                       cmd->msg_status, cmd->host_status, cmd->driver_status);
2028                 res = 1;
2029         } else if (unlikely(cmd->host_status)) {
2030                 if ((cmd->host_status == DID_REQUEUE) ||
2031                     (cmd->host_status == DID_IMM_RETRY) ||
2032                     (cmd->host_status == DID_SOFT_ERROR) ||
2033                     (cmd->host_status == DID_ABORT)) {
2034                         scst_set_busy(cmd);
2035                 } else {
2036                         TRACE(TRACE_SCSI|TRACE_MINOR, "Host status %x "
2037                                 "received, returning HARDWARE ERROR instead",
2038                                 cmd->host_status);
2039                         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2040                 }
2041         }
2042
2043         TRACE_EXIT_RES(res);
2044         return res;
2045 }
2046
2047 static int scst_done_cmd_check(struct scst_cmd *cmd, int *pres)
2048 {
2049         int res = 0, rc;
2050
2051         TRACE_ENTRY();
2052
2053         if (unlikely(cmd->cdb[0] == REQUEST_SENSE)) {
2054                 if (cmd->internal)
2055                         cmd = scst_complete_request_sense(cmd);
2056         } else if (unlikely(scst_check_auto_sense(cmd))) {
2057                 PRINT_INFO("Command finished with CHECK CONDITION, but "
2058                             "without sense data (opcode 0x%x), issuing "
2059                             "REQUEST SENSE", cmd->cdb[0]);
2060                 rc = scst_prepare_request_sense(cmd);
2061                 if (rc > 0) {
2062                         *pres = rc;
2063                         res = 1;
2064                         goto out;
2065                 } else {
2066                         PRINT_ERROR("%s", "Unable to issue REQUEST SENSE, "
2067                                     "returning HARDWARE ERROR");
2068                         scst_set_cmd_error(cmd,
2069                                 SCST_LOAD_SENSE(scst_sense_hardw_error));
2070                 }
2071         } else if (unlikely(scst_check_sense(cmd))) {
2072                 *pres = SCST_CMD_STATE_RES_CONT_SAME;
2073                 res = 1;
2074                 goto out;
2075         }
2076
2077         if (likely(scsi_status_is_good(cmd->status))) {
2078                 unsigned char type = cmd->dev->handler->type;
2079                 if ((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10) &&
2080                     cmd->tgt_dev->acg_dev->rd_only_flag &&
2081                     (type == TYPE_DISK || type == TYPE_WORM || type == TYPE_MOD ||
2082                      type == TYPE_TAPE)) {
2083                         int32_t length;
2084                         uint8_t *address;
2085
2086                         length = scst_get_buf_first(cmd, &address);
2087                         if (length <= 0)
2088                                 goto out;
2089                         if (length > 2 && cmd->cdb[0] == MODE_SENSE)
2090                                 address[2] |= 0x80;   /* Write Protect*/
2091                         else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10)
2092                                 address[3] |= 0x80;   /* Write Protect*/
2093                         scst_put_buf(cmd, address);
2094                 }
2095
2096                 /* 
2097                  * Check and clear NormACA option for the device, if necessary,
2098                  * since we don't support ACA
2099                  */
2100                 if ((cmd->cdb[0] == INQUIRY) &&
2101                     !(cmd->cdb[1] & SCST_INQ_EVPD/* Std INQUIRY data (no EVPD) */) &&
2102                     (cmd->resp_data_len > SCST_INQ_BYTE3)) {
2103                         uint8_t *buffer;
2104                         int buflen;
2105
2106                         /* ToDo: all pages ?? */
2107                         buflen = scst_get_buf_first(cmd, &buffer);
2108                         if (buflen > SCST_INQ_BYTE3) {
2109 #ifdef EXTRACHECKS
2110                                 if (buffer[SCST_INQ_BYTE3] & SCST_INQ_NORMACA_BIT) {
2111                                         PRINT_INFO("NormACA set for device: "
2112                                             "lun=%Ld, type 0x%02x", 
2113                                             (uint64_t)cmd->lun, buffer[0]);
2114                                 }
2115 #endif
2116                                 buffer[SCST_INQ_BYTE3] &= ~SCST_INQ_NORMACA_BIT;
2117                         } else {
2118                                 PRINT_ERROR("%s", "Unable to get INQUIRY "
2119                                     "buffer");
2120                                 scst_set_cmd_error(cmd,
2121                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
2122                         }
2123                         if (buflen > 0)
2124                                 scst_put_buf(cmd, buffer);
2125                 }
2126
2127                 if (unlikely((cmd->cdb[0] == MODE_SELECT) || 
2128                     (cmd->cdb[0] == MODE_SELECT_10) ||
2129                     (cmd->cdb[0] == LOG_SELECT))) {
2130                         TRACE(TRACE_SCSI, "MODE/LOG SELECT succeeded (LUN %Ld)",
2131                                 (uint64_t)cmd->lun);
2132                         cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
2133                         *pres = SCST_CMD_STATE_RES_CONT_SAME;
2134                         res = 1;
2135                         goto out;
2136                 }
2137         } else {
2138                 if ((cmd->cdb[0] == RESERVE) || (cmd->cdb[0] == RESERVE_10)) {
2139                         if (!test_bit(SCST_TGT_DEV_RESERVED,
2140                                         &cmd->tgt_dev->tgt_dev_flags)) {
2141                                 struct scst_tgt_dev *tgt_dev_tmp;
2142                                 struct scst_device *dev = cmd->dev;
2143
2144                                 TRACE(TRACE_SCSI, "Real RESERVE failed lun=%Ld, status=%x",
2145                                       (uint64_t)cmd->lun, cmd->status);
2146                                 TRACE_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer,
2147                                              sizeof(cmd->sense_buffer));
2148
2149                                 /* Clearing the reservation */
2150                                 spin_lock_bh(&dev->dev_lock);
2151                                 list_for_each_entry(tgt_dev_tmp, &dev->dev_tgt_dev_list,
2152                                                     dev_tgt_dev_list_entry) {
2153                                         clear_bit(SCST_TGT_DEV_RESERVED, 
2154                                                 &tgt_dev_tmp->tgt_dev_flags);
2155                                 }
2156                                 dev->dev_reserved = 0;
2157                                 spin_unlock_bh(&dev->dev_lock);
2158                         }
2159                 }
2160
2161                 /* Check for MODE PARAMETERS CHANGED UA */
2162                 if ((cmd->dev->scsi_dev != NULL) &&
2163                     (cmd->status == SAM_STAT_CHECK_CONDITION) && 
2164                     SCST_SENSE_VALID(cmd->sense_buffer) &&
2165                     scst_is_ua_sense(cmd->sense_buffer) &&
2166                     (cmd->sense_buffer[12] == 0x2a) &&
2167                     (cmd->sense_buffer[13] == 0x01)) {
2168                         TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun %Ld)",
2169                                 (uint64_t)cmd->lun);
2170                         cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
2171                         *pres = SCST_CMD_STATE_RES_CONT_SAME;
2172                         res = 1;
2173                         goto out;
2174                 }
2175         }
2176
2177 out:
2178         TRACE_EXIT_RES(res);
2179         return res;
2180 }
2181
2182 static int scst_pre_dev_done(struct scst_cmd *cmd)
2183 {
2184         int res = SCST_CMD_STATE_RES_CONT_SAME, rc;
2185
2186         TRACE_ENTRY();
2187
2188         rc = scst_done_cmd_check(cmd, &res);
2189         if (rc)
2190                 goto out;
2191
2192         cmd->state = SCST_CMD_STATE_DEV_DONE;
2193
2194 out:
2195         TRACE_EXIT_HRES(res);
2196         return res;
2197 }
2198
2199 static int scst_mode_select_checks(struct scst_cmd *cmd)
2200 {
2201         int res = SCST_CMD_STATE_RES_CONT_SAME;
2202         int atomic = scst_cmd_atomic(cmd);
2203
2204         TRACE_ENTRY();
2205
2206         if (likely(scsi_status_is_good(cmd->status))) {
2207                 if (unlikely((cmd->cdb[0] == MODE_SELECT) || 
2208                     (cmd->cdb[0] == MODE_SELECT_10) ||
2209                     (cmd->cdb[0] == LOG_SELECT))) {
2210                         struct scst_device *dev = cmd->dev;
2211                         if (atomic && (dev->scsi_dev != NULL)) {
2212                                 TRACE_DBG("%s", "MODE/LOG SELECT: thread "
2213                                         "context required");
2214                                 res = SCST_CMD_STATE_RES_NEED_THREAD;
2215                                 goto out;
2216                         }
2217
2218                         TRACE(TRACE_SCSI, "MODE/LOG SELECT succeeded, "
2219                                 "setting the SELECT UA (lun=%Ld)", 
2220                                 (uint64_t)cmd->lun);
2221
2222                         spin_lock_bh(&dev->dev_lock);
2223                         spin_lock(&scst_temp_UA_lock);
2224                         if (cmd->cdb[0] == LOG_SELECT) {
2225                                 scst_set_sense(scst_temp_UA,
2226                                         sizeof(scst_temp_UA),
2227                                         UNIT_ATTENTION, 0x2a, 0x02);
2228                         } else {
2229                                 scst_set_sense(scst_temp_UA,
2230                                         sizeof(scst_temp_UA),
2231                                         UNIT_ATTENTION, 0x2a, 0x01);
2232                         }
2233                         scst_dev_check_set_local_UA(dev, cmd, scst_temp_UA,
2234                                 sizeof(scst_temp_UA));
2235                         spin_unlock(&scst_temp_UA_lock);
2236                         spin_unlock_bh(&dev->dev_lock);
2237
2238                         if (dev->scsi_dev != NULL)
2239                                 scst_obtain_device_parameters(dev);
2240                 }
2241         } else if ((cmd->status == SAM_STAT_CHECK_CONDITION) && 
2242                     SCST_SENSE_VALID(cmd->sense_buffer) &&
2243                     scst_is_ua_sense(cmd->sense_buffer) &&
2244                     (cmd->sense_buffer[12] == 0x2a) &&
2245                     (cmd->sense_buffer[13] == 0x01)) {
2246                 if (atomic) {
2247                         TRACE_DBG("%s", "MODE PARAMETERS CHANGED UA: thread "
2248                                 "context required");
2249                         res = SCST_CMD_STATE_RES_NEED_THREAD;
2250                         goto out;
2251                 }
2252
2253                 TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun %Ld): "
2254                         "getting new parameters", (uint64_t)cmd->lun);
2255
2256                 scst_obtain_device_parameters(cmd->dev);
2257         } else
2258                 sBUG();
2259
2260         cmd->state = SCST_CMD_STATE_DEV_DONE;
2261
2262 out:
2263         TRACE_EXIT_HRES(res);
2264         return res;
2265 }
2266
2267 static void scst_inc_check_expected_sn(struct scst_cmd *cmd)
2268 {
2269         struct scst_cmd *c;
2270
2271         if (likely(cmd->sn_set))
2272                 scst_inc_expected_sn(cmd->tgt_dev, cmd->sn_slot);
2273
2274         c = scst_check_deferred_commands(cmd->tgt_dev);
2275         if (c != NULL) {
2276                 unsigned long flags;
2277                 spin_lock_irqsave(&c->cmd_lists->cmd_list_lock, flags);
2278                 TRACE_SN("Adding cmd %p to active cmd list", c);
2279                 list_add_tail(&c->cmd_list_entry,
2280                         &c->cmd_lists->active_cmd_list);
2281                 wake_up(&c->cmd_lists->cmd_list_waitQ);
2282                 spin_unlock_irqrestore(&c->cmd_lists->cmd_list_lock, flags);
2283         }
2284 }
2285
2286 static int scst_dev_done(struct scst_cmd *cmd)
2287 {
2288         int res = SCST_CMD_STATE_RES_CONT_SAME;
2289         int state;
2290         int atomic = scst_cmd_atomic(cmd);
2291
2292         TRACE_ENTRY();
2293
2294         if (atomic && !cmd->dev->handler->dev_done_atomic) {
2295                 TRACE_DBG("Dev handler %s dev_done() can not be "
2296                       "called in atomic context, rescheduling to the thread",
2297                       cmd->dev->handler->name);
2298                 res = SCST_CMD_STATE_RES_NEED_THREAD;
2299                 goto out;
2300         }
2301
2302         state = SCST_CMD_STATE_PRE_XMIT_RESP;
2303         if (likely(!scst_is_cmd_local(cmd)) && 
2304             likely(cmd->dev->handler->dev_done != NULL))
2305         {
2306                 int rc;
2307                 TRACE_DBG("Calling dev handler %s dev_done(%p)",
2308                       cmd->dev->handler->name, cmd);
2309                 rc = cmd->dev->handler->dev_done(cmd);
2310                 TRACE_DBG("Dev handler %s dev_done() returned %d",
2311                       cmd->dev->handler->name, rc);
2312                 if (rc != SCST_CMD_STATE_DEFAULT)
2313                         state = rc;
2314         }
2315
2316         switch (state) {
2317         case SCST_CMD_STATE_PRE_XMIT_RESP:
2318         case SCST_CMD_STATE_DEV_PARSE:
2319         case SCST_CMD_STATE_PRE_PARSE:
2320         case SCST_CMD_STATE_PREPARE_SPACE:
2321         case SCST_CMD_STATE_RDY_TO_XFER:
2322         case SCST_CMD_STATE_TGT_PRE_EXEC:
2323         case SCST_CMD_STATE_SEND_TO_MIDLEV:
2324         case SCST_CMD_STATE_PRE_DEV_DONE:
2325         case SCST_CMD_STATE_MODE_SELECT_CHECKS:
2326         case SCST_CMD_STATE_DEV_DONE:
2327         case SCST_CMD_STATE_XMIT_RESP:
2328         case SCST_CMD_STATE_FINISHED:
2329                 cmd->state = state;
2330                 res = SCST_CMD_STATE_RES_CONT_SAME;
2331                 break;
2332
2333         case SCST_CMD_STATE_NEED_THREAD_CTX:
2334                 TRACE_DBG("Dev handler %s dev_done() requested "
2335                       "thread context, rescheduling",
2336                       cmd->dev->handler->name);
2337                 res = SCST_CMD_STATE_RES_NEED_THREAD;
2338                 break;
2339
2340         default:
2341                 if (state >= 0) {
2342                         PRINT_ERROR("Dev handler %s dev_done() returned "
2343                                 "invalid cmd state %d", 
2344                                 cmd->dev->handler->name, state);
2345                 } else {
2346                         PRINT_ERROR("Dev handler %s dev_done() returned "
2347                                 "error %d", cmd->dev->handler->name, 
2348                                 state);
2349                 }
2350                 scst_set_cmd_error(cmd,
2351                            SCST_LOAD_SENSE(scst_sense_hardw_error));
2352                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
2353                 res = SCST_CMD_STATE_RES_CONT_SAME;
2354                 break;
2355         }
2356
2357         if (cmd->needs_unblocking)
2358                 scst_unblock_dev_cmd(cmd);
2359
2360         if (likely(cmd->dec_on_dev_needed))
2361                 scst_dec_on_dev_cmd(cmd);
2362
2363         if (cmd->inc_expected_sn_on_done && cmd->sent_to_midlev)
2364                 scst_inc_check_expected_sn(cmd);
2365
2366 out:
2367         TRACE_EXIT_HRES(res);
2368         return res;
2369 }
2370
2371 static int scst_pre_xmit_response(struct scst_cmd *cmd)
2372 {
2373         int res;
2374
2375         TRACE_ENTRY();
2376
2377         if (cmd->tgt_dev != NULL) {
2378                 if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
2379                         scst_on_hq_cmd_response(cmd);
2380
2381                 if (unlikely(!cmd->sent_to_midlev)) {
2382                         TRACE_SN("cmd %p was not sent to mid-lev (sn %ld, set %d)",
2383                                 cmd, cmd->sn, cmd->sn_set);
2384                         scst_unblock_deferred(cmd->tgt_dev, cmd);
2385                         cmd->sent_to_midlev = 1;
2386                 }
2387         }
2388
2389         /*
2390          * If we don't remove cmd from the search list here, before
2391          * submitting it for transmittion, we will have a race, when for
2392          * some reason cmd's release is delayed after transmittion and
2393          * initiator sends cmd with the same tag => it is possible that
2394          * a wrong cmd will be found by find() functions.
2395          */
2396         spin_lock_irq(&cmd->sess->sess_list_lock);
2397         list_del(&cmd->search_cmd_list_entry);
2398         spin_unlock_irq(&cmd->sess->sess_list_lock);
2399
2400         if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)))
2401                 scst_xmit_process_aborted_cmd(cmd);
2402
2403         if (unlikely(test_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags))) {
2404                 TRACE_MGMT_DBG("Flag NO_RESP set for cmd %p (tag %llu), skipping",
2405                         cmd, cmd->tag);
2406                 cmd->state = SCST_CMD_STATE_FINISHED;
2407                 res = SCST_CMD_STATE_RES_CONT_SAME;
2408                 goto out;
2409         }
2410
2411         cmd->state = SCST_CMD_STATE_XMIT_RESP;
2412         res = SCST_CMD_STATE_RES_CONT_SAME;
2413
2414 out:
2415         TRACE_EXIT_HRES(res);
2416         return res;
2417 }
2418
2419 static int scst_xmit_response(struct scst_cmd *cmd)
2420 {
2421         int res, rc;
2422         int atomic = scst_cmd_atomic(cmd);
2423
2424         TRACE_ENTRY();
2425
2426         if (atomic && !cmd->tgtt->xmit_response_atomic) {
2427                 TRACE_DBG("%s", "xmit_response() can not be "
2428                       "called in atomic context, rescheduling to the thread");
2429                 res = SCST_CMD_STATE_RES_NEED_THREAD;
2430                 goto out;
2431         }
2432
2433 #ifdef DEBUG_TM
2434         if (cmd->tm_dbg_delayed && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
2435                 if (atomic && !cmd->tgtt->xmit_response_atomic) {
2436                         TRACE_MGMT_DBG("%s", "DEBUG_TM delayed cmd needs a thread");
2437                         res = SCST_CMD_STATE_RES_NEED_THREAD;
2438                         goto out;
2439                 }
2440                 TRACE_MGMT_DBG("Delaying cmd %p (tag %llu) for 1 second",
2441                         cmd, cmd->tag);
2442                 schedule_timeout_uninterruptible(HZ);
2443         }
2444 #endif
2445
2446         while (1) {
2447                 int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds);
2448
2449                 res = SCST_CMD_STATE_RES_CONT_NEXT;
2450                 cmd->state = SCST_CMD_STATE_XMIT_WAIT;
2451
2452                 TRACE_DBG("Calling xmit_response(%p)", cmd);
2453
2454 #if defined(DEBUG) || defined(TRACING)
2455                 if (cmd->sg) {
2456                         int i;
2457                         struct scatterlist *sg = cmd->sg;
2458                         TRACE(TRACE_SEND_BOT,
2459                               "Xmitting %d S/G(s) at %p sg[0].page at %p",
2460                               cmd->sg_cnt, sg, (void*)sg[0].page);
2461                         for(i = 0; i < cmd->sg_cnt; ++i) {
2462                                 TRACE_BUFF_FLAG(TRACE_SEND_BOT,
2463                                     "Xmitting sg", page_address(sg[i].page),
2464                                     sg[i].length);
2465                         }
2466                 }
2467 #endif
2468
2469 #ifdef DEBUG_RETRY
2470                 if (((scst_random() % 100) == 77))
2471                         rc = SCST_TGT_RES_QUEUE_FULL;
2472                 else
2473 #endif
2474                         rc = cmd->tgtt->xmit_response(cmd);
2475                 TRACE_DBG("xmit_response() returned %d", rc);
2476
2477                 if (likely(rc == SCST_TGT_RES_SUCCESS))
2478                         goto out;
2479
2480                 /* Restore the previous state */
2481                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
2482
2483                 switch (rc) {
2484                 case SCST_TGT_RES_QUEUE_FULL:
2485                         if (scst_queue_retry_cmd(cmd, finished_cmds) == 0)
2486                                 break;
2487                         else
2488                                 continue;
2489
2490                 case SCST_TGT_RES_NEED_THREAD_CTX:
2491                         TRACE_DBG("Target driver %s xmit_response() "
2492                               "requested thread context, rescheduling",
2493                               cmd->tgtt->name);
2494                         res = SCST_CMD_STATE_RES_NEED_THREAD;
2495                         break;
2496
2497                 default:
2498                         goto out_error;
2499                 }
2500                 break;
2501         }
2502
2503 out:
2504         /* Caution: cmd can be already dead here */
2505         TRACE_EXIT_HRES(res);
2506         return res;
2507
2508 out_error:
2509         if (rc == SCST_TGT_RES_FATAL_ERROR) {
2510                 PRINT_ERROR("Target driver %s xmit_response() returned "
2511                         "fatal error", cmd->tgtt->name);
2512         } else {
2513                 PRINT_ERROR("Target driver %s xmit_response() returned "
2514                         "invalid value %d", cmd->tgtt->name, rc);
2515         }
2516         scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2517         cmd->state = SCST_CMD_STATE_FINISHED;
2518         res = SCST_CMD_STATE_RES_CONT_SAME;
2519         goto out;
2520 }
2521
2522 void scst_tgt_cmd_done(struct scst_cmd *cmd)
2523 {
2524         TRACE_ENTRY();
2525
2526         sBUG_ON(cmd->state != SCST_CMD_STATE_XMIT_WAIT);
2527
2528         cmd->state = SCST_CMD_STATE_FINISHED;
2529         scst_proccess_redirect_cmd(cmd, scst_get_context(), 1);
2530
2531         TRACE_EXIT();
2532         return;
2533 }
2534
2535 static int scst_finish_cmd(struct scst_cmd *cmd)
2536 {
2537         int res;
2538
2539         TRACE_ENTRY();
2540
2541         atomic_dec(&cmd->sess->sess_cmd_count);
2542
2543         if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
2544                 TRACE_MGMT_DBG("Aborted cmd %p finished (cmd_ref %d, "
2545                         "scst_cmd_count %d)", cmd, atomic_read(&cmd->cmd_ref),
2546                         atomic_read(&scst_cmd_count));
2547         }
2548
2549         if (unlikely(cmd->delivery_status != SCST_CMD_DELIVERY_SUCCESS)) {
2550                 if ((cmd->tgt_dev != NULL) &&
2551                     scst_is_ua_sense(cmd->sense_buffer)) {
2552                         /* This UA delivery failed, so requeue it */
2553                         scst_check_set_UA(cmd->tgt_dev, cmd->sense_buffer,
2554                                         sizeof(cmd->sense_buffer), 1);
2555                 }
2556         }
2557
2558         scst_cmd_put(cmd);
2559
2560         res = SCST_CMD_STATE_RES_CONT_NEXT;
2561
2562         TRACE_EXIT_HRES(res);
2563         return res;
2564 }
2565
2566 /*
2567  * No locks, but it must be externally serialized (see comment for
2568  * scst_cmd_init_done() in scsi_tgt.h)
2569  */
2570 static void scst_cmd_set_sn(struct scst_cmd *cmd)
2571 {
2572         struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
2573         unsigned long flags;
2574
2575         if (scst_is_implicit_hq(cmd)) {
2576                 TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "Implicit HQ cmd %p", cmd);
2577                 cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE;
2578         }
2579
2580         /* Optimized for lockless fast path */
2581
2582         scst_check_debug_sn(cmd);
2583
2584         if (cmd->dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER)
2585                 cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
2586
2587         switch(cmd->queue_type) {
2588         case SCST_CMD_QUEUE_SIMPLE:
2589         case SCST_CMD_QUEUE_UNTAGGED:
2590 #if 1 /* temporary, ToDo */
2591                 if (scst_cmd_is_expected_set(cmd)) {
2592                         if (cmd->expected_data_direction == SCST_DATA_READ)
2593                                 goto ordered;
2594                 } else
2595                         goto ordered;
2596 #endif
2597                 if (likely(tgt_dev->num_free_sn_slots >= 0)) {
2598                         if (atomic_inc_return(tgt_dev->cur_sn_slot) == 1) {
2599                                 tgt_dev->curr_sn++;
2600                                 TRACE_SN("Incremented curr_sn %ld",
2601                                         tgt_dev->curr_sn);
2602                         }
2603                         cmd->sn_slot = tgt_dev->cur_sn_slot;
2604                         cmd->sn = tgt_dev->curr_sn;
2605                         
2606                         tgt_dev->prev_cmd_ordered = 0;
2607                 } else {
2608                         TRACE(TRACE_MINOR, "%s", "Not enough SN slots");
2609                         goto ordered;
2610                 }
2611                 break;
2612
2613         case SCST_CMD_QUEUE_ORDERED:
2614                 TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "ORDERED cmd %p "
2615                         "(op %x)", cmd, cmd->cdb[0]);
2616 ordered:
2617                 if (!tgt_dev->prev_cmd_ordered) {
2618                         spin_lock_irqsave(&tgt_dev->sn_lock, flags);
2619                         tgt_dev->num_free_sn_slots--;
2620                         smp_mb();
2621                         if ((tgt_dev->num_free_sn_slots >= 0) &&
2622                             (atomic_read(tgt_dev->cur_sn_slot) > 0)) {
2623                                 do {
2624                                         tgt_dev->cur_sn_slot++;
2625                                         if (tgt_dev->cur_sn_slot == 
2626                                                 tgt_dev->sn_slots +
2627                                                 ARRAY_SIZE(tgt_dev->sn_slots))
2628                                             tgt_dev->cur_sn_slot = tgt_dev->sn_slots;
2629                                 } while(atomic_read(tgt_dev->cur_sn_slot) != 0);
2630                                 TRACE_SN("New cur SN slot %zd",
2631                                         tgt_dev->cur_sn_slot-tgt_dev->sn_slots);
2632                         } else
2633                                 tgt_dev->num_free_sn_slots++;
2634                         spin_unlock_irqrestore(&tgt_dev->sn_lock, flags);
2635                 }
2636                 tgt_dev->prev_cmd_ordered = 1;
2637                 tgt_dev->curr_sn++;
2638                 cmd->sn = tgt_dev->curr_sn;
2639                 break;
2640
2641         case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
2642                 TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "HQ cmd %p "
2643                         "(op %x)", cmd, cmd->cdb[0]);
2644                 spin_lock_irqsave(&tgt_dev->sn_lock, flags);
2645                 tgt_dev->hq_cmd_count++;
2646                 spin_unlock_irqrestore(&tgt_dev->sn_lock, flags);
2647                 goto out;
2648
2649         default:
2650                 sBUG();
2651         }
2652
2653         TRACE_SN("cmd(%p)->sn: %ld (tgt_dev %p, *cur_sn_slot %d, "
2654                 "num_free_sn_slots %d, prev_cmd_ordered %ld, "
2655                 "cur_sn_slot %zd)", cmd, cmd->sn, tgt_dev,
2656                 atomic_read(tgt_dev->cur_sn_slot), 
2657                 tgt_dev->num_free_sn_slots, tgt_dev->prev_cmd_ordered,
2658                 tgt_dev->cur_sn_slot-tgt_dev->sn_slots);
2659
2660         cmd->sn_set = 1;
2661 out:
2662         return;
2663 }
2664
2665 /*
2666  * Returns 0 on success, > 0 when we need to wait for unblock,
2667  * < 0 if there is no device (lun) or device type handler.
2668  *
2669  * No locks, but might be on IRQ, protection is done by the
2670  * suspended activity.
2671  */
2672 static int scst_translate_lun(struct scst_cmd *cmd)
2673 {
2674         struct scst_tgt_dev *tgt_dev = NULL;
2675         int res;
2676
2677         TRACE_ENTRY();
2678
2679         __scst_get(1);
2680
2681         if (likely(!test_bit(SCST_FLAG_SUSPENDED, &scst_flags))) {
2682                 struct list_head *sess_tgt_dev_list_head =
2683                         &cmd->sess->sess_tgt_dev_list_hash[HASH_VAL(cmd->lun)];
2684                 TRACE_DBG("Finding tgt_dev for cmd %p (lun %Ld)", cmd,
2685                         (uint64_t)cmd->lun);
2686                 res = -1;
2687                 list_for_each_entry(tgt_dev, sess_tgt_dev_list_head,
2688                                 sess_tgt_dev_list_entry) {
2689                         if (tgt_dev->lun == cmd->lun) {
2690                                 TRACE_DBG("tgt_dev %p found", tgt_dev);
2691
2692                                 if (unlikely(tgt_dev->dev->handler == &scst_null_devtype)) {
2693                                         PRINT_INFO("Dev handler for device "
2694                                           "%Ld is NULL, the device will not be "
2695                                           "visible remotely", (uint64_t)cmd->lun);
2696                                         break;
2697                                 }
2698                                 
2699                                 cmd->cmd_lists = tgt_dev->dev->p_cmd_lists;
2700                                 cmd->tgt_dev = tgt_dev;
2701                                 cmd->dev = tgt_dev->dev;
2702
2703                                 res = 0;
2704                                 break;
2705                         }
2706                 }
2707                 if (res != 0) {
2708                         TRACE(TRACE_MINOR, "tgt_dev for lun %Ld not found, command to "
2709                                 "unexisting LU?", (uint64_t)cmd->lun);
2710                         __scst_put();
2711                 }
2712         } else {
2713                 TRACE_MGMT_DBG("%s", "FLAG SUSPENDED set, skipping");
2714                 __scst_put();
2715                 res = 1;
2716         }
2717
2718         TRACE_EXIT_RES(res);
2719         return res;
2720 }
2721
2722 /*
2723  * No locks, but might be on IRQ
2724  *
2725  * Returns 0 on success, > 0 when we need to wait for unblock,
2726  * < 0 if there is no device (lun) or device type handler.
2727  */
2728 static int __scst_init_cmd(struct scst_cmd *cmd)
2729 {
2730         int res = 0;
2731
2732         TRACE_ENTRY();
2733
2734         res = scst_translate_lun(cmd);
2735         if (likely(res == 0)) {
2736                 int cnt;
2737                 cmd->state = SCST_CMD_STATE_PRE_PARSE;
2738                 cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
2739                 if (unlikely(cnt > SCST_MAX_TGT_DEV_COMMANDS)) {
2740                         TRACE(TRACE_MGMT_MINOR, "Too many pending commands (%d) in "
2741                                 "session, returning BUSY to initiator \"%s\"",
2742                                 cnt, (cmd->sess->initiator_name[0] == '\0') ?
2743                                   "Anonymous" : cmd->sess->initiator_name);
2744                         goto out_busy;
2745                 }
2746                 cnt = atomic_inc_return(&cmd->dev->dev_cmd_count);
2747                 if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) {
2748                         TRACE(TRACE_MGMT_MINOR, "Too many pending device commands "
2749                                 "(%d), returning BUSY to initiator \"%s\"",
2750                                 cnt, (cmd->sess->initiator_name[0] == '\0') ?
2751                                   "Anonymous" : cmd->sess->initiator_name);
2752                         goto out_busy;
2753                 }
2754                 if (!cmd->set_sn_on_restart_cmd)
2755                         scst_cmd_set_sn(cmd);
2756         } else if (res < 0) {
2757                 TRACE_DBG("Finishing cmd %p", cmd);
2758                 scst_set_cmd_error(cmd,
2759                            SCST_LOAD_SENSE(scst_sense_lun_not_supported));
2760                 cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
2761         } else
2762                 goto out;
2763
2764 out:
2765         TRACE_EXIT_RES(res);
2766         return res;
2767
2768 out_busy:
2769         scst_set_busy(cmd);
2770         cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
2771         goto out;
2772 }
2773
2774 /* Called under scst_init_lock and IRQs disabled */
2775 static void scst_do_job_init(void)
2776 {
2777         struct scst_cmd *cmd;
2778         int susp;
2779
2780         TRACE_ENTRY();
2781
2782 restart:
2783         susp = test_bit(SCST_FLAG_SUSPENDED, &scst_flags);
2784         if (scst_init_poll_cnt > 0)
2785                 scst_init_poll_cnt--;
2786
2787         list_for_each_entry(cmd, &scst_init_cmd_list, cmd_list_entry) {
2788                 int rc;
2789                 if (susp && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
2790                         continue;
2791                 if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
2792                         spin_unlock_irq(&scst_init_lock);
2793                         rc = __scst_init_cmd(cmd);
2794                         spin_lock_irq(&scst_init_lock);
2795                         if (rc > 0) {
2796                                 TRACE_MGMT_DBG("%s", "FLAG SUSPENDED set, restarting");
2797                                 goto restart;
2798                         }
2799                 } else {
2800                         TRACE_MGMT_DBG("Aborting not inited cmd %p (tag %llu)",
2801                                 cmd, cmd->tag);
2802                         cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
2803                 }
2804
2805                 /*
2806                  * Deleting cmd from init cmd list after __scst_init_cmd()
2807                  * is necessary to keep the check in scst_init_cmd() correct
2808                  * to preserve the commands order.
2809                  *
2810                  * We don't care about the race, when init cmd list is empty
2811                  * and one command detected that it just was not empty, so
2812                  * it's inserting to it, but another command at the same time
2813                  * seeing init cmd list empty and goes directly, because it
2814                  * could affect only commands from the same initiator to the
2815                  * same tgt_dev, but init_cmd_done() doesn't guarantee the order
2816                  * in case of simultaneous such calls anyway.
2817                  */
2818                 TRACE_MGMT_DBG("Deleting cmd %p from init cmd list", cmd);
2819                 list_del(&cmd->cmd_list_entry);
2820                 spin_unlock(&scst_init_lock);
2821
2822                 spin_lock(&cmd->cmd_lists->cmd_list_lock);
2823                 TRACE_MGMT_DBG("Adding cmd %p to active cmd list", cmd);
2824                 if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
2825                         list_add(&cmd->cmd_list_entry,
2826                                 &cmd->cmd_lists->active_cmd_list);
2827                 else
2828                         list_add_tail(&cmd->cmd_list_entry,
2829                                 &cmd->cmd_lists->active_cmd_list);
2830                 wake_up(&cmd->cmd_lists->cmd_list_waitQ);
2831                 spin_unlock(&cmd->cmd_lists->cmd_list_lock);
2832
2833                 spin_lock(&scst_init_lock);
2834                 goto restart;
2835         }
2836
2837         if (susp != test_bit(SCST_FLAG_SUSPENDED, &scst_flags))
2838                 goto restart;
2839
2840         TRACE_EXIT();
2841         return;
2842 }
2843
2844 static inline int test_init_cmd_list(void)
2845 {
2846         int res = (!list_empty(&scst_init_cmd_list) &&
2847                    !test_bit(SCST_FLAG_SUSPENDED, &scst_flags)) ||
2848                   unlikely(kthread_should_stop()) ||
2849                   (scst_init_poll_cnt > 0);
2850         return res;
2851 }
2852
2853 int scst_init_cmd_thread(void *arg)
2854 {
2855         TRACE_ENTRY();
2856
2857         current->flags |= PF_NOFREEZE;
2858
2859         set_user_nice(current, -20);
2860
2861         spin_lock_irq(&scst_init_lock);
2862         while(!kthread_should_stop()) {
2863                 wait_queue_t wait;
2864                 init_waitqueue_entry(&wait, current);
2865
2866                 if (!test_init_cmd_list()) {
2867                         add_wait_queue_exclusive(&scst_init_cmd_list_waitQ,
2868                                                  &wait);
2869                         for (;;) {
2870                                 set_current_state(TASK_INTERRUPTIBLE);
2871                                 if (test_init_cmd_list())
2872                                         break;
2873                                 spin_unlock_irq(&scst_init_lock);
2874                                 schedule();
2875                                 spin_lock_irq(&scst_init_lock);
2876                         }
2877                         set_current_state(TASK_RUNNING);
2878                         remove_wait_queue(&scst_init_cmd_list_waitQ, &wait);
2879                 }
2880                 scst_do_job_init();
2881         }
2882         spin_unlock_irq(&scst_init_lock);
2883
2884         /*
2885          * If kthread_should_stop() is true, we are guaranteed to be
2886          * on the module unload, so scst_init_cmd_list must be empty.
2887          */
2888         sBUG_ON(!list_empty(&scst_init_cmd_list));
2889
2890         TRACE_EXIT();
2891         return 0;
2892 }
2893
2894 /* Called with no locks held */
2895 void scst_process_active_cmd(struct scst_cmd *cmd, int context)
2896 {
2897         int res;
2898
2899         TRACE_ENTRY();
2900
2901         EXTRACHECKS_BUG_ON(in_irq());
2902
2903         cmd->atomic = (context == SCST_CONTEXT_DIRECT_ATOMIC);
2904
2905         do {
2906                 switch (cmd->state) {
2907                 case SCST_CMD_STATE_PRE_PARSE:
2908                         res = scst_pre_parse(cmd);
2909                         break;
2910
2911                 case SCST_CMD_STATE_DEV_PARSE:
2912                         res = scst_parse_cmd(cmd);
2913                         break;
2914
2915                 case SCST_CMD_STATE_PREPARE_SPACE:
2916                         res = scst_prepare_space(cmd);
2917                         break;
2918
2919                 case SCST_CMD_STATE_RDY_TO_XFER:
2920                         res = scst_rdy_to_xfer(cmd);
2921                         break;
2922
2923                 case SCST_CMD_STATE_TGT_PRE_EXEC:
2924                         res = scst_tgt_pre_exec(cmd);
2925                         break;
2926
2927                 case SCST_CMD_STATE_SEND_TO_MIDLEV:
2928                         if (tm_dbg_check_cmd(cmd) != 0) {
2929                                 res = SCST_CMD_STATE_RES_CONT_NEXT;
2930                                 TRACE_MGMT_DBG("Skipping cmd %p (tag %llu), "
2931                                         "because of TM DBG delay", cmd,
2932                                         cmd->tag);
2933                                 break;
2934                         }
2935                         res = scst_send_to_midlev(&cmd);
2936                         /* !! At this point cmd, sess & tgt_dev can be already freed !! */
2937                         break;
2938
2939                 case SCST_CMD_STATE_PRE_DEV_DONE:
2940                         res = scst_pre_dev_done(cmd);
2941                         break;
2942
2943                 case SCST_CMD_STATE_MODE_SELECT_CHECKS:
2944                         res = scst_mode_select_checks(cmd);
2945                         break;
2946
2947                 case SCST_CMD_STATE_DEV_DONE:
2948                         res = scst_dev_done(cmd);
2949                         break;
2950
2951                 case SCST_CMD_STATE_PRE_XMIT_RESP:
2952                         res = scst_pre_xmit_response(cmd);
2953                         break;
2954
2955                 case SCST_CMD_STATE_XMIT_RESP:
2956                         res = scst_xmit_response(cmd);
2957                         break;
2958
2959                 case SCST_CMD_STATE_FINISHED:
2960                         res = scst_finish_cmd(cmd);
2961                         break;
2962
2963                 default:
2964                         PRINT_ERROR("cmd (%p) in state %d, but shouldn't be",
2965                                cmd, cmd->state);
2966                         sBUG();
2967                         res = SCST_CMD_STATE_RES_CONT_NEXT;
2968                         break;
2969                 }
2970         } while(res == SCST_CMD_STATE_RES_CONT_SAME);
2971
2972         if (res == SCST_CMD_STATE_RES_CONT_NEXT) {
2973                 /* None */
2974         } else if (res == SCST_CMD_STATE_RES_NEED_THREAD) {
2975                 spin_lock_irq(&cmd->cmd_lists->cmd_list_lock);
2976                 switch (cmd->state) {
2977                 case SCST_CMD_STATE_PRE_PARSE:
2978                 case SCST_CMD_STATE_DEV_PARSE:
2979                 case SCST_CMD_STATE_PREPARE_SPACE:
2980                 case SCST_CMD_STATE_RDY_TO_XFER:
2981                 case SCST_CMD_STATE_TGT_PRE_EXEC:
2982                 case SCST_CMD_STATE_SEND_TO_MIDLEV:
2983                 case SCST_CMD_STATE_PRE_DEV_DONE:
2984                 case SCST_CMD_STATE_MODE_SELECT_CHECKS:
2985                 case SCST_CMD_STATE_DEV_DONE:
2986                 case SCST_CMD_STATE_PRE_XMIT_RESP:
2987                 case SCST_CMD_STATE_XMIT_RESP:
2988                 case SCST_CMD_STATE_FINISHED:
2989                         TRACE_DBG("Adding cmd %p to head of active cmd list", cmd);
2990                         list_add(&cmd->cmd_list_entry,
2991                                 &cmd->cmd_lists->active_cmd_list);
2992                         break;
2993 #ifdef EXTRACHECKS
2994                 /* not very valid commands */
2995                 case SCST_CMD_STATE_DEFAULT:
2996                 case SCST_CMD_STATE_NEED_THREAD_CTX:
2997                         PRINT_ERROR("cmd %p is in state %d, not putting on "
2998                                 "useful list (left on scst cmd list)", cmd, 
2999                                 cmd->state);
3000                         spin_unlock_irq(&cmd->cmd_lists->cmd_list_lock);
3001                         sBUG();
3002                         spin_lock_irq(&cmd->cmd_lists->cmd_list_lock);
3003                         break;
3004 #endif
3005                 default:
3006                         break;
3007                 }
3008                 wake_up(&cmd->cmd_lists->cmd_list_waitQ);
3009                 spin_unlock_irq(&cmd->cmd_lists->cmd_list_lock);
3010         } else
3011                 sBUG();
3012
3013         TRACE_EXIT();
3014         return;
3015 }
3016
3017 /* Called under cmd_list_lock and IRQs disabled */
3018 static void scst_do_job_active(struct list_head *cmd_list,
3019         spinlock_t *cmd_list_lock, int context)
3020 {
3021         TRACE_ENTRY();
3022
3023 #ifdef EXTRACHECKS
3024         WARN_ON((context != SCST_CONTEXT_DIRECT_ATOMIC) && 
3025                 (context != SCST_CONTEXT_DIRECT));
3026 #endif
3027
3028         while (!list_empty(cmd_list)) {
3029                 struct scst_cmd *cmd = list_entry(cmd_list->next, typeof(*cmd),
3030                                         cmd_list_entry);
3031                 TRACE_DBG("Deleting cmd %p from active cmd list", cmd);
3032                 list_del(&cmd->cmd_list_entry);
3033                 spin_unlock_irq(cmd_list_lock);
3034                 scst_process_active_cmd(cmd, context);
3035                 spin_lock_irq(cmd_list_lock);
3036         }
3037
3038         TRACE_EXIT();
3039         return;
3040 }
3041
3042 static inline int test_cmd_lists(struct scst_cmd_lists *p_cmd_lists)
3043 {
3044         int res = !list_empty(&p_cmd_lists->active_cmd_list) ||
3045             unlikely(kthread_should_stop()) ||
3046             tm_dbg_is_release();
3047         return res;
3048 }
3049
3050 int scst_cmd_thread(void *arg)
3051 {
3052         struct scst_cmd_lists *p_cmd_lists = (struct scst_cmd_lists*)arg;
3053
3054         TRACE_ENTRY();
3055
3056 #if 0
3057         set_user_nice(current, 10);
3058 #endif
3059         current->flags |= PF_NOFREEZE;
3060
3061         spin_lock_irq(&p_cmd_lists->cmd_list_lock);
3062         while (!kthread_should_stop()) {
3063                 wait_queue_t wait;
3064                 init_waitqueue_entry(&wait, current);
3065
3066                 if (!test_cmd_lists(p_cmd_lists)) {
3067                         add_wait_queue_exclusive(&p_cmd_lists->cmd_list_waitQ,
3068                                 &wait);
3069                         for (;;) {
3070                                 set_current_state(TASK_INTERRUPTIBLE);
3071                                 if (test_cmd_lists(p_cmd_lists))
3072                                         break;
3073                                 spin_unlock_irq(&p_cmd_lists->cmd_list_lock);
3074                                 schedule();
3075                                 spin_lock_irq(&p_cmd_lists->cmd_list_lock);
3076                         }
3077                         set_current_state(TASK_RUNNING);
3078                         remove_wait_queue(&p_cmd_lists->cmd_list_waitQ, &wait);
3079                 }
3080
3081                 if (tm_dbg_is_release()) {
3082                         spin_unlock_irq(&p_cmd_lists->cmd_list_lock);
3083                         tm_dbg_check_released_cmds();
3084                         spin_lock_irq(&p_cmd_lists->cmd_list_lock);
3085                 }
3086
3087                 scst_do_job_active(&p_cmd_lists->active_cmd_list,
3088                         &p_cmd_lists->cmd_list_lock, SCST_CONTEXT_DIRECT);
3089         }
3090         spin_unlock_irq(&p_cmd_lists->cmd_list_lock);
3091
3092 #ifdef EXTRACHECKS
3093         /*
3094          * If kthread_should_stop() is true, we are guaranteed to be either
3095          * on the module unload, or there must be at least one other thread to
3096          * process the commands lists.
3097          */
3098         if (p_cmd_lists == &scst_main_cmd_lists) {
3099                 sBUG_ON((scst_threads_info.nr_cmd_threads == 1) &&
3100                          !list_empty(&scst_main_cmd_lists.active_cmd_list));
3101         }
3102 #endif
3103
3104         TRACE_EXIT();
3105         return 0;
3106 }
3107
3108 void scst_cmd_tasklet(long p)
3109 {
3110         struct scst_tasklet *t = (struct scst_tasklet*)p;
3111
3112         TRACE_ENTRY();
3113
3114         spin_lock_irq(&t->tasklet_lock);
3115         scst_do_job_active(&t->tasklet_cmd_list, &t->tasklet_lock,
3116                 SCST_CONTEXT_DIRECT_ATOMIC);
3117         spin_unlock_irq(&t->tasklet_lock);
3118
3119         TRACE_EXIT();
3120         return;
3121 }
3122
3123 /*
3124  * Returns 0 on success, < 0 if there is no device handler or
3125  * > 0 if SCST_FLAG_SUSPENDED set and SCST_FLAG_SUSPENDING - not.
3126  * No locks, protection is done by the suspended activity.
3127  */
3128 static int scst_mgmt_translate_lun(struct scst_mgmt_cmd *mcmd)
3129 {
3130         struct scst_tgt_dev *tgt_dev = NULL;
3131         struct list_head *sess_tgt_dev_list_head;
3132         int res = -1;
3133
3134         TRACE_ENTRY();
3135
3136         TRACE_DBG("Finding tgt_dev for mgmt cmd %p (lun %Ld)", mcmd,
3137               (uint64_t)mcmd->lun);
3138
3139         __scst_get(1);
3140
3141         if (unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags) &&
3142                      !test_bit(SCST_FLAG_SUSPENDING, &scst_flags))) {
3143                 TRACE_MGMT_DBG("%s", "FLAG SUSPENDED set, skipping");
3144                 __scst_put();
3145                 res = 1;
3146                 goto out;
3147         }
3148
3149         sess_tgt_dev_list_head =
3150                 &mcmd->sess->sess_tgt_dev_list_hash[HASH_VAL(mcmd->lun)];
3151         list_for_each_entry(tgt_dev, sess_tgt_dev_list_head,
3152                         sess_tgt_dev_list_entry) {
3153                 if (tgt_dev->lun == mcmd->lun) {
3154                         TRACE_DBG("tgt_dev %p found", tgt_dev);
3155                         mcmd->mcmd_tgt_dev = tgt_dev;
3156                         res = 0;
3157                         break;
3158                 }
3159         }
3160         if (mcmd->mcmd_tgt_dev == NULL)
3161                 __scst_put();
3162
3163 out:
3164         TRACE_EXIT_HRES(res);
3165         return res;
3166 }
3167
3168 /* No locks */
3169 void scst_complete_cmd_mgmt(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd)
3170 {
3171         TRACE_ENTRY();
3172
3173         spin_lock_irq(&scst_mcmd_lock);
3174
3175         TRACE_MGMT_DBG("cmd %p completed (tag %llu, mcmd %p, "
3176                 "mcmd->cmd_wait_count %d)", cmd, cmd->tag, mcmd,
3177                 mcmd->cmd_wait_count);
3178
3179         cmd->mgmt_cmnd = NULL;
3180
3181         if (cmd->completed)
3182                 mcmd->completed_cmd_count++;
3183
3184         mcmd->cmd_wait_count--;
3185         if (mcmd->cmd_wait_count > 0) {
3186                 TRACE_MGMT_DBG("cmd_wait_count(%d) not 0, skipping",
3187                         mcmd->cmd_wait_count);
3188                 goto out_unlock;
3189         }
3190
3191         mcmd->state = SCST_MGMT_CMD_STATE_DONE;
3192
3193         if (mcmd->completed) {
3194                 TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd list",
3195                         mcmd);
3196                 list_add_tail(&mcmd->mgmt_cmd_list_entry,
3197                         &scst_active_mgmt_cmd_list);
3198         }
3199
3200         spin_unlock_irq(&scst_mcmd_lock);
3201
3202         wake_up(&scst_mgmt_cmd_list_waitQ);
3203
3204 out:
3205         TRACE_EXIT();
3206         return;
3207
3208 out_unlock:
3209         spin_unlock_irq(&scst_mcmd_lock);
3210         goto out;
3211 }
3212
3213 static int scst_call_dev_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
3214         struct scst_tgt_dev *tgt_dev, int set_status)
3215 {
3216         int res = SCST_DEV_TM_NOT_COMPLETED;
3217         struct scst_dev_type *h = tgt_dev->dev->handler;
3218
3219         if (h->task_mgmt_fn) {
3220                 TRACE_MGMT_DBG("Calling dev handler %s task_mgmt_fn(fn=%d)",
3221                         h->name, mcmd->fn);
3222                 EXTRACHECKS_BUG_ON(in_irq());
3223                 res = h->task_mgmt_fn(mcmd, tgt_dev);
3224                 TRACE_MGMT_DBG("Dev handler %s task_mgmt_fn() returned %d",
3225                       h->name, res);
3226                 if (set_status && (res != SCST_DEV_TM_NOT_COMPLETED))
3227                         mcmd->status = res;
3228         }
3229         return res;
3230 }
3231
3232 static inline int scst_is_strict_mgmt_fn(int mgmt_fn)
3233 {
3234         switch(mgmt_fn) {
3235 #ifdef ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING
3236                 case SCST_ABORT_TASK:
3237 #endif
3238 #if 0
3239                 case SCST_ABORT_TASK_SET:
3240                 case SCST_CLEAR_TASK_SET:
3241 #endif
3242                         return 1;
3243                 default:
3244                         return 0;
3245         }
3246 }
3247
3248 /* 
3249  * Might be called under sess_list_lock and IRQ off + BHs also off
3250  * Returns -1 if command is being executed (ABORT failed), 0 otherwise
3251  */
3252 void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
3253         int other_ini, int call_dev_task_mgmt_fn)
3254 {
3255         TRACE_ENTRY();
3256
3257         TRACE(((mcmd != NULL) && (mcmd->fn == SCST_ABORT_TASK)) ? TRACE_MGMT_MINOR : TRACE_MGMT,
3258                 "Aborting cmd %p (tag %llu)", cmd, cmd->tag);
3259
3260         if (other_ini) {
3261                 set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
3262                 smp_mb__after_set_bit();
3263         } else {
3264                 /* Might be necessary if command aborted several times */
3265                 clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
3266         }
3267         set_bit(SCST_CMD_ABORTED, &cmd->cmd_flags);
3268         smp_mb__after_set_bit();
3269
3270         if (cmd->tgt_dev == NULL) {
3271                 unsigned long flags;
3272                 spin_lock_irqsave(&scst_init_lock, flags);
3273                 scst_init_poll_cnt++;
3274                 spin_unlock_irqrestore(&scst_init_lock, flags);
3275                 wake_up(&scst_init_cmd_list_waitQ);
3276         }
3277
3278         if (call_dev_task_mgmt_fn && (cmd->tgt_dev != NULL)) {
3279                 EXTRACHECKS_BUG_ON(irqs_disabled());
3280                 scst_call_dev_task_mgmt_fn(mcmd, cmd->tgt_dev, 1);
3281         }
3282
3283         if (mcmd) {
3284                 unsigned long flags;
3285                 /*
3286                  * Delay the response until the command's finish in
3287                  * order to guarantee that "no further responses from
3288                  * the task are sent to the SCSI initiator port" after
3289                  * response from the TM function is sent (SAM). Plus,
3290                  * we must wait here to be sure that we won't receive
3291                  * double commands with the same tag.
3292                  */
3293                 TRACE((mcmd->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT,
3294                         "cmd %p (tag %llu) being executed/xmitted (state %d), "
3295                         "deferring ABORT...", cmd, cmd->tag, cmd->state);
3296 #ifdef EXTRACHECKS
3297                 if (cmd->mgmt_cmnd) {
3298                         printk(KERN_ALERT "cmd %p (tag %llu, state %d) "
3299                                 "has non-NULL mgmt_cmnd %p!!! Current "
3300                                 "mcmd %p\n", cmd, cmd->tag, cmd->state,
3301                                 cmd->mgmt_cmnd, mcmd);
3302                 }
3303 #endif
3304                 sBUG_ON(cmd->mgmt_cmnd);
3305                 spin_lock_irqsave(&scst_mcmd_lock, flags);
3306                 mcmd->cmd_wait_count++;
3307                 spin_unlock_irqrestore(&scst_mcmd_lock, flags);
3308                 /* cmd can't die here or sess_list_lock already taken */
3309                 cmd->mgmt_cmnd = mcmd;
3310         }
3311
3312         tm_dbg_release_cmd(cmd);
3313
3314         TRACE_EXIT();
3315         return;
3316 }
3317
3318 /* No locks */
3319 static int scst_set_mcmd_next_state(struct scst_mgmt_cmd *mcmd)
3320 {
3321         int res;
3322         spin_lock_irq(&scst_mcmd_lock);
3323         if (mcmd->cmd_wait_count != 0) {
3324                 TRACE_MGMT_DBG("cmd_wait_count(%d) not 0, preparing to "
3325                         "wait", mcmd->cmd_wait_count);
3326                 mcmd->state = SCST_MGMT_CMD_STATE_EXECUTING;
3327                 res = -1;
3328         } else {
3329                 mcmd->state = SCST_MGMT_CMD_STATE_DONE;
3330                 res = 0;
3331         }
3332         mcmd->completed = 1;
3333         spin_unlock_irq(&scst_mcmd_lock);
3334         return res;
3335 }
3336
3337 static int __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd)
3338 {
3339         int res;
3340         if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
3341                 TRACE_MGMT_DBG("Adding aborted blocked cmd %p to active cmd "
3342                         "list", cmd);
3343                 spin_lock(&cmd->cmd_lists->cmd_list_lock);
3344                 list_add_tail(&cmd->cmd_list_entry,
3345                         &cmd->cmd_lists->active_cmd_list);
3346                 wake_up(&cmd->cmd_lists->cmd_list_waitQ);
3347                 spin_unlock(&cmd->cmd_lists->cmd_list_lock);
3348                 res = 1;
3349         } else
3350                 res = 0;
3351         return res;
3352 }
3353
3354 static void scst_unblock_aborted_cmds(int scst_mutex_held)
3355 {
3356         struct scst_device *dev;
3357
3358         TRACE_ENTRY();
3359
3360         if (!scst_mutex_held)
3361                 mutex_lock(&scst_mutex);
3362
3363         list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
3364                 struct scst_cmd *cmd, *tcmd;
3365                 struct scst_tgt_dev *tgt_dev;
3366                 spin_lock_bh(&dev->dev_lock);
3367                 local_irq_disable();
3368                 list_for_each_entry_safe(cmd, tcmd, &dev->blocked_cmd_list,
3369                                         blocked_cmd_list_entry) {
3370                         if (__scst_check_unblock_aborted_cmd(cmd))
3371                                 list_del(&cmd->blocked_cmd_list_entry);
3372                 }
3373                 local_irq_enable();
3374                 spin_unlock_bh(&dev->dev_lock);
3375
3376                 local_irq_disable();
3377                 list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
3378                                          dev_tgt_dev_list_entry) {
3379                         spin_lock(&tgt_dev->sn_lock);
3380                         list_for_each_entry_safe(cmd, tcmd,
3381                                         &tgt_dev->deferred_cmd_list,
3382                                         sn_cmd_list_entry) {
3383                                 if (__scst_check_unblock_aborted_cmd(cmd)) {
3384                                         TRACE_MGMT_DBG("Deleting aborted SN "
3385                                                 "cmd %p from SN list", cmd);
3386                                         tgt_dev->def_cmd_count--;
3387                                         list_del(&cmd->sn_cmd_list_entry);
3388                                 }
3389                         }
3390                         spin_unlock(&tgt_dev->sn_lock);
3391                 }
3392                 local_irq_enable();
3393         }
3394
3395         if (!scst_mutex_held)
3396                 mutex_unlock(&scst_mutex);
3397
3398         TRACE_EXIT();
3399         return;
3400 }
3401
3402 static void __scst_abort_task_set(struct scst_mgmt_cmd *mcmd,
3403         struct scst_tgt_dev *tgt_dev, int other_ini, int scst_mutex_held)
3404 {
3405         struct scst_cmd *cmd;
3406         struct scst_session *sess = tgt_dev->sess;
3407
3408         TRACE_ENTRY();
3409
3410         spin_lock_irq(&sess->sess_list_lock);
3411
3412         TRACE_DBG("Searching in search cmd list (sess=%p)", sess);
3413         list_for_each_entry(cmd, &sess->search_cmd_list, 
3414                         search_cmd_list_entry) {
3415                 if ((cmd->tgt_dev == tgt_dev) ||
3416                     ((cmd->tgt_dev == NULL) && 
3417                      (cmd->lun == tgt_dev->lun))) {
3418                         if (mcmd->cmd_sn_set) {
3419                                 sBUG_ON(!cmd->tgt_sn_set);
3420                                 if (scst_sn_before(mcmd->cmd_sn, cmd->tgt_sn) ||
3421                                     (mcmd->cmd_sn == cmd->tgt_sn))
3422                                         continue;
3423                         }
3424                         scst_abort_cmd(cmd, mcmd, other_ini, 0);
3425                 }
3426         }
3427         spin_unlock_irq(&sess->sess_list_lock);
3428
3429         scst_unblock_aborted_cmds(scst_mutex_held);
3430
3431         TRACE_EXIT();
3432         return;
3433 }
3434
3435 /* Returns 0 if the command processing should be continued, <0 otherwise */
3436 static int scst_abort_task_set(struct scst_mgmt_cmd *mcmd)
3437 {
3438         int res;
3439         struct scst_tgt_dev *tgt_dev = mcmd->mcmd_tgt_dev;
3440         struct scst_device *dev = tgt_dev->dev;
3441
3442         TRACE(TRACE_MGMT, "Aborting task set (lun=%Ld, mcmd=%p)",
3443                 tgt_dev->lun, mcmd);
3444
3445         mcmd->needs_unblocking = 1;
3446
3447         spin_lock_bh(&dev->dev_lock);
3448         __scst_block_dev(dev);
3449         spin_unlock_bh(&dev->dev_lock);
3450
3451         __scst_abort_task_set(mcmd, tgt_dev, 0, 0);
3452         scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 0);
3453
3454         res = scst_set_mcmd_next_state(mcmd);
3455
3456         TRACE_EXIT_RES(res);
3457         return res;
3458 }
3459
3460 static int scst_is_cmd_belongs_to_dev(struct scst_cmd *cmd,
3461         struct scst_device *dev)
3462 {
3463         struct scst_tgt_dev *tgt_dev = NULL;
3464         struct list_head *sess_tgt_dev_list_head;
3465         int res = 0;
3466
3467         TRACE_ENTRY();
3468
3469         TRACE_DBG("Finding match for dev %p and cmd %p (lun %Ld)", dev, cmd,
3470               (uint64_t)cmd->lun);
3471
3472         sess_tgt_dev_list_head =
3473                 &cmd->sess->sess_tgt_dev_list_hash[HASH_VAL(cmd->lun)];
3474         list_for_each_entry(tgt_dev, sess_tgt_dev_list_head,
3475                         sess_tgt_dev_list_entry) {
3476                 if (tgt_dev->lun == cmd->lun) {
3477                         TRACE_DBG("dev %p found", tgt_dev->dev);
3478                         res = (tgt_dev->dev == dev);
3479                         goto out;
3480                 }
3481         }
3482
3483 out:
3484         TRACE_EXIT_HRES(res);
3485         return res;
3486 }
3487
3488 /* Returns 0 if the command processing should be continued, <0 otherwise */
3489 static int scst_clear_task_set(struct scst_mgmt_cmd *mcmd)
3490 {
3491         int res;
3492         struct scst_device *dev = mcmd->mcmd_tgt_dev->dev;
3493         struct scst_tgt_dev *tgt_dev;
3494         LIST_HEAD(UA_tgt_devs);
3495
3496         TRACE_ENTRY();
3497
3498         TRACE(TRACE_MGMT, "Clearing task set (lun=%Ld, mcmd=%p)",
3499                 (uint64_t)mcmd->lun, mcmd);
3500
3501         mcmd->needs_unblocking = 1;
3502
3503         spin_lock_bh(&dev->dev_lock);
3504         __scst_block_dev(dev);
3505         spin_unlock_bh(&dev->dev_lock);
3506
3507         __scst_abort_task_set(mcmd, mcmd->mcmd_tgt_dev, 0, 0);
3508
3509         mutex_lock(&scst_mutex);
3510
3511         list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, 
3512                         dev_tgt_dev_list_entry) {
3513                 struct scst_session *sess = tgt_dev->sess;
3514                 struct scst_cmd *cmd;
3515                 int aborted = 0;
3516
3517                 if (tgt_dev == mcmd->mcmd_tgt_dev)
3518                         continue;
3519
3520                 spin_lock_irq(&sess->sess_list_lock);
3521
3522                 TRACE_DBG("Searching in search cmd list (sess=%p)", sess);
3523                 list_for_each_entry(cmd, &sess->search_cmd_list, 
3524                                 search_cmd_list_entry) {
3525                         if ((cmd->dev == dev) ||
3526                             ((cmd->dev == NULL) && 
3527                              scst_is_cmd_belongs_to_dev(cmd, dev))) {
3528                                 scst_abort_cmd(cmd, mcmd, 1, 0);
3529                                 aborted = 1;
3530                         }
3531                 }
3532                 spin_unlock_irq(&sess->sess_list_lock);
3533
3534                 if (aborted)
3535                         list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
3536                                         &UA_tgt_devs);
3537         }
3538