Minor cleanup
[mirror/scst/.git] / qla2x00t / qla2x00-target / qla2x00t.c
1 /*
2  *  qla2x00t.c
3  *  
4  *  Copyright (C) 2004-2006 Vladislav Bolkhovitin <vst@vlnb.net>
5  *                          Leonid Stoljar
6  *                          Nathaniel Clark <nate@misrule.us>
7  *
8  *  Qlogic 2x00 SCSI target driver.
9  *  
10  *  This program is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU General Public License
12  *  as published by the Free Software Foundation, version 2
13  *  of the License.
14  * 
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  *  GNU General Public License for more details.
19  */
20
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/types.h>
24 #include <linux/version.h>
25 #include <linux/blkdev.h>
26 #include <linux/interrupt.h>
27 #include <scsi/scsi.h>
28 #include <scsi/scsi_host.h>
29 #include <linux/pci.h>
30 #include <linux/delay.h>
31
32 #include <linux/list.h>
33
34 #include <scsi_tgt.h>
35
36 /* Necessary to have equal structures with the initiator */
37 #if defined(FC_IP_SUPPORT)
38 #include <linux/ip.h>
39 #include <linux/if_arp.h>
40 #include <linux/skbuff.h>
41 #include "qla_ip.h"
42 #endif
43
44 #include "qla2x00t.h"
45
46 /* Undefine the initiator driver's own DEBUG symbol */
47 #undef DEBUG
48
49 #ifdef DEBUG_TGT
50 #define DEBUG
51 #endif
52
53 #include <scst_debug.h>
54 #include <scst_debug.c>
55
56 #ifndef FC_TARGET_SUPPORT
57 #error "FC_TARGET_SUPPORT is NOT DEFINED"
58 #endif
59
60 /*
61  * Whether to use slab cach instead of kmalloc/kfree
62  */
63 #if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB)
64 #define Q2T_CACHE_FLAGS ( SLAB_RED_ZONE | SLAB_POISON )
65 #else
66 #define Q2T_CACHE_FLAGS 0L
67 #endif
68
69 #ifdef DEBUG
70 #define SCST_DEFAULT_QLA_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
71         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \
72         TRACE_MINOR | TRACE_SPECIAL)
73 #else
74 # ifdef TRACING
75 #define SCST_DEFAULT_QLA_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
76         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL)
77 # endif
78 #endif
79
80 static int q2t_target_detect(struct scst_tgt_template *templ);
81 static int q2t_target_release(struct scst_tgt *scst_tgt);
82 static int q2t_xmit_response(struct scst_cmd *scst_cmd);
83 static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd);
84 static void q2t_on_free_cmd(struct scst_cmd *scst_cmd);
85 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd);
86
87 /* Predefs for callbacks handed to qla2xxx(target) */
88 static void q2t_host_action(scsi_qla_host_t *ha,
89         qla2x_tgt_host_action_t action);
90 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt);
91 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha,
92         uint16_t *mailbox);
93 static void q2t_ctio_completion(scsi_qla_host_t *ha, uint32_t handle);
94 static void q2t_host_action(scsi_qla_host_t *ha,
95         qla2x_tgt_host_action_t action);
96 static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
97         atio_entry_t *atio);
98
99 /*
100  * Global Variables
101  */
102
103 #if defined(DEBUG) || defined(TRACING)
104 unsigned long trace_flag = SCST_DEFAULT_QLA_LOG_FLAGS;
105 #endif
106
107 struct scst_tgt_template tgt_template = {
108       name:"qla2x00tgt",
109       sg_tablesize:0,
110       use_clustering:1,
111 #ifdef DEBUG_WORK_IN_THREAD
112       xmit_response_atomic:0,
113       rdy_to_xfer_atomic:0,
114 #else
115       xmit_response_atomic:1,
116       rdy_to_xfer_atomic:1,
117 #endif
118       detect:q2t_target_detect,
119       release:q2t_target_release,
120       xmit_response:q2t_xmit_response,
121       rdy_to_xfer:q2t_rdy_to_xfer,
122       on_free_cmd:q2t_on_free_cmd,
123       task_mgmt_fn_done:q2t_task_mgmt_fn_done,
124 };
125
126 kmem_cache_t *q2t_cmd_cachep = NULL;
127 static struct qla2x_tgt_target tgt_data;
128
129 /*
130  * Functions
131  */
132
133 static inline int test_tgt_sess_count(struct q2t_tgt *tgt, scsi_qla_host_t *ha)
134 {
135         return (atomic_read(&tgt->sess_count) == 0);
136 }
137
138 /* ha->hardware_lock supposed to be held on entry */
139 static inline void q2t_exec_queue(scsi_qla_host_t *ha)
140 {
141         tgt_data.isp_cmd(ha);
142 }
143
144 /* ha->hardware_lock supposed to be held on entry */
145 static void q2t_modify_command_count(scsi_qla_host_t *ha, int cmd_count,
146         int imm_count)
147 {
148         modify_lun_entry_t *pkt;
149
150         TRACE_ENTRY();
151
152         TRACE_DBG("Sending MODIFY_LUN ha %p, cmd %d, imm %d", 
153                   ha, cmd_count, imm_count);
154
155         pkt = (modify_lun_entry_t *)tgt_data.req_pkt(ha);
156         ha->tgt->modify_lun_expected++;
157
158         pkt->entry_type = MODIFY_LUN_TYPE;
159         pkt->entry_count = 1;
160         if (cmd_count < 0) {
161                 pkt->operators = MODIFY_LUN_CMD_SUB;    /* Subtract from command count */
162                 pkt->command_count = -cmd_count;
163         } else if (cmd_count > 0){
164                 pkt->operators = MODIFY_LUN_CMD_ADD;    /* Add to command count */
165                 pkt->command_count = cmd_count;
166         }
167
168         if (imm_count < 0) {
169                 pkt->operators |= MODIFY_LUN_IMM_SUB;
170                 pkt->immed_notify_count = -imm_count;
171         } else if (imm_count > 0) {
172                 pkt->operators |= MODIFY_LUN_IMM_ADD;
173                 pkt->immed_notify_count = imm_count;
174         }
175
176         pkt->timeout = 0;       /* Use default */
177         q2t_exec_queue(ha);
178
179         TRACE_EXIT();
180         return;
181 }
182
183 /* ha->hardware_lock supposed to be held on entry */
184 static void __q2t_send_notify_ack(scsi_qla_host_t *ha,
185          uint16_t target_id, uint16_t status, uint16_t task_flags,
186          uint16_t seq_id, uint32_t add_flags,  uint16_t resp_code,
187          int resp_code_valid, uint16_t ox_id)
188 {
189         nack_entry_t *ntfy;
190         
191         TRACE_ENTRY();
192
193         /* Send marker if required */
194         if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
195                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
196                             "failed", ha->instance);
197                 goto out;
198         }
199
200         ntfy = (nack_entry_t *)tgt_data.req_pkt(ha);
201
202         if (ha->tgt != NULL)
203                 ha->tgt->notify_ack_expected++;
204
205         memset(ntfy, 0, sizeof(*ntfy));
206         ntfy->entry_type = NOTIFY_ACK_TYPE;
207         ntfy->entry_count = 1;
208         SET_TARGET_ID(ha, ntfy->target, target_id);
209         ntfy->status = status;
210         ntfy->task_flags = task_flags;
211         ntfy->seq_id = seq_id;
212         /* Do not increment here, the chip isn't decrementing */
213         /* ntfy->flags = __constant_cpu_to_le16(NOTIFY_ACK_RES_COUNT); */
214         ntfy->flags |= cpu_to_le16(add_flags);
215         ntfy->ox_id = ox_id;
216
217         if (resp_code_valid) {
218                 ntfy->resp_code = cpu_to_le16(resp_code);
219                 ntfy->flags |=
220                         __constant_cpu_to_le16(NOTIFY_ACK_TM_RESP_CODE_VALID);
221         }
222
223         TRACE(TRACE_SCSI, "Sending Notify Ack Seq %#x -> I %#x St %#x RC %#x",
224               le16_to_cpu(seq_id), target_id, le16_to_cpu(status),
225               le16_to_cpu(ntfy->resp_code));
226
227         q2t_exec_queue(ha);
228
229 out:
230         TRACE_EXIT();
231         return;
232 }
233 /* ha->hardware_lock supposed to be held on entry */
234 static inline void q2t_send_notify_ack(scsi_qla_host_t *ha,
235         notify_entry_t *iocb, uint32_t add_flags, uint16_t resp_code,
236         int resp_code_valid)
237 {
238         __q2t_send_notify_ack(ha,  GET_TARGET_ID(ha, iocb), iocb->status,
239               iocb->task_flags, iocb->seq_id, add_flags, resp_code,
240               resp_code_valid, iocb->ox_id);
241 }
242
243 /* 
244  * register with initiator driver (but target mode isn't enabled till
245  * it's turned on via sysfs)
246  */
247 static int q2t_target_detect(struct scst_tgt_template *templ)
248 {
249         int res;
250         struct qla2x_tgt_initiator itd = {
251                 magic:QLA2X_TARGET_MAGIC,
252                 tgt_response_pkt:q2t_response_pkt,
253                 tgt_ctio_completion:q2t_ctio_completion,
254                 tgt_async_event:q2t_async_event,
255                 tgt_host_action:q2t_host_action,
256         };
257
258         TRACE_ENTRY();
259
260         res = qla2xxx_tgt_register_driver(&itd, &tgt_data);
261         if (res != 0) {
262                 PRINT_ERROR("Unable to register driver: %d", res);
263                 goto out;
264         }
265
266         if (tgt_data.magic != QLA2X_INITIATOR_MAGIC) {
267                 PRINT_ERROR("Wrong version of the initiator driver: %d", 
268                             tgt_data.magic);
269                 res = -EINVAL;
270         }
271
272 out:
273         TRACE_EXIT();
274         return res;
275 }
276
277 /* no lock held */
278 static void q2t_free_session_done(struct scst_session *scst_sess)
279 {
280         struct q2t_sess *sess;
281         struct q2t_tgt *tgt;
282
283         TRACE_ENTRY();
284
285         BUG_ON(scst_sess == NULL);
286         sess = (struct q2t_sess *)scst_sess_get_tgt_priv(scst_sess);
287         BUG_ON(sess == NULL);
288         tgt = sess->tgt;
289
290         kfree(sess);
291
292         if (tgt == NULL)
293                 goto out;
294
295         TRACE(TRACE_DEBUG|TRACE_MGMT, 
296               "tgt->handle %x empty(sess_list) %d sess_count %d", 
297               tgt->handle, list_empty(&tgt->sess_list),
298               atomic_read(&tgt->sess_count));
299
300         smp_mb__before_atomic_dec();
301         if (atomic_dec_and_test(&tgt->sess_count)) {
302                 smp_mb__after_atomic_dec();
303                 wake_up_all(&tgt->waitQ);
304         }
305
306 out:
307         TRACE_EXIT();
308         return;
309 }
310
311 /* ha->hardware_lock supposed to be held on entry */
312 static void q2t_unreg_sess(struct q2t_sess *sess)
313 {
314         TRACE_ENTRY();
315
316         if (sess == NULL)
317                 goto out;
318
319         list_del(&sess->list);
320
321         PRINT_INFO("qla2x00tgt(%ld): session for loop_id %d deleted",
322                 sess->tgt->ha->instance, sess->loop_id);
323
324         /* 
325          * Any commands for this session will be finished regularly,
326          * because we must not drop SCSI commands on transport level,
327          * at least without any response to the initiator.
328          */
329
330         scst_unregister_session(sess->scst_sess, 0, q2t_free_session_done);
331
332 out:
333         TRACE_EXIT();
334         return;
335 }
336
337 /* ha->hardware_lock supposed to be held on entry */
338 static void q2t_port_logout(scsi_qla_host_t *ha, int loop_id)
339 {
340         struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
341
342         TRACE(TRACE_DEBUG|TRACE_MGMT, 
343               "scsi(%ld) Unregistering session %p loop_id=%d",
344               ha->host_no, sess, loop_id);
345
346         q2t_unreg_sess(sess);
347 }
348
349 /* ha->hardware_lock supposed to be held on entry */
350 static void q2t_clear_tgt_db(struct q2t_tgt *tgt)
351 {
352         struct q2t_sess *sess, *sess_tmp;
353
354         TRACE_ENTRY();
355
356         TRACE(TRACE_DEBUG|TRACE_MGMT, "Clearing targets DB %p", tgt);
357
358         list_for_each_entry_safe(sess, sess_tmp, &tgt->sess_list, list) {
359                 q2t_unreg_sess(sess);
360         }
361
362         /* At this point tgt could be already dead */
363
364         TRACE_MGMT_DBG("Finished clearing Target DB %p", tgt);
365
366         TRACE_EXIT();
367         return;
368 }
369
370 /* should be called w/out hardware_lock, but tgt should be
371  * unfindable at this point */
372 static int q2t_target_release(struct scst_tgt *scst_tgt)
373 {
374         int res = 0;
375         struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
376         scsi_qla_host_t *ha = tgt->ha;
377         unsigned long flags = 0;
378
379         TRACE_ENTRY();
380
381         spin_lock_irqsave(&ha->hardware_lock, flags);
382         tgt->tgt_shutdown = 1;
383         q2t_clear_tgt_db(tgt);
384         spin_unlock_irqrestore(&ha->hardware_lock, flags);
385
386         wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha));
387
388         /* big hammer */
389         if(!ha->flags.host_shutting_down) 
390                 tgt_data.disable_lun(ha);
391
392         /* wait for sessions to clear out (just in case) */
393         wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha)); 
394         
395         TRACE_MGMT_DBG("Finished waiting for tgt %p: empty(sess_list)=%d "
396                 "sess_count=%d", tgt, list_empty(&tgt->sess_list),
397                 atomic_read(&tgt->sess_count));
398
399         scst_tgt_set_tgt_priv(scst_tgt, NULL);
400
401         kfree(tgt);
402
403         TRACE_EXIT_RES(res);
404         return res;
405 }
406
407 static int q2t_pci_map_calc_cnt(struct q2t_prm *prm)
408 {
409         int res = 0;
410
411         BUG_ON(prm->sg_cnt == 0);
412
413         /* 32 bit S/G Data Transfer */
414         prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, prm->sg, prm->sg_cnt,
415                                scst_to_tgt_dma_dir(prm->data_direction));
416         if (unlikely(prm->seg_cnt == 0))
417                 goto out_err;
418         /*
419          * If greater than four sg entries then we need to allocate
420          * the continuation entries
421          */
422         if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) {
423                 prm->req_cnt += (uint16_t)(prm->seg_cnt -
424                                 prm->tgt->datasegs_per_cmd) /
425                                 prm->tgt->datasegs_per_cont;
426                 if (((uint16_t)(prm->seg_cnt - prm->tgt->datasegs_per_cmd)) %
427                                         prm->tgt->datasegs_per_cont) 
428                 {
429                         prm->req_cnt++;
430                 }
431         }
432
433 out:
434         TRACE_DBG("seg_cnt=%d, req_cnt=%d, res=%d", prm->seg_cnt, 
435                 prm->req_cnt, res);
436         return res;
437
438 out_err:
439         PRINT_ERROR("qla2x00tgt(%ld): PCI mapping failed: sg_cnt=%d", 
440                 prm->tgt->ha->instance, prm->sg_cnt);
441         res = -1;
442         goto out;
443 }
444
445 /* ha->hardware_lock supposed to be held on entry */
446 static inline uint32_t q2t_make_handle(scsi_qla_host_t *ha)
447 {
448         uint32_t h;
449
450         h = ha->current_cmd;
451         /* always increment cmd handle */
452         do {
453                 ++h;
454                 if (h > MAX_OUTSTANDING_COMMANDS) {
455                         h = 0;
456                 }
457                 if (h == ha->current_cmd) {
458                         TRACE(TRACE_OUT_OF_MEM, "Ran out of empty cmd slots "
459                                 "in ha %p", ha);
460                         h = Q2T_NULL_HANDLE;
461                         break;
462                 }
463         } while ((h == Q2T_NULL_HANDLE) ||
464                  (h == Q2T_BUSY_HANDLE) ||
465                  (h == Q2T_SKIP_HANDLE) || 
466                  (ha->cmds[h] != NULL));
467
468         if (h != Q2T_NULL_HANDLE)
469                 ha->current_cmd = h;
470
471         return h;
472 }
473
474 /* ha->hardware_lock supposed to be held on entry */
475 /*
476  * NOTE: About CTIO_COMPLETION_HANDLE
477  *  This is checked for in qla2x00_process_response_queue() to see
478  *  if a handle coming back in a multi-complete should come to the tgt driver
479  *  or be handled there by qla2xxx
480  */
481 static void q2t_build_ctio_pkt(struct q2t_prm *prm)
482 {
483         uint16_t timeout;
484         uint32_t h;
485
486         prm->pkt = (ctio_common_entry_t *)tgt_data.req_pkt(prm->tgt->ha);
487
488         if (prm->tgt->tgt_enable_64bit_addr)
489                 prm->pkt->entry_type = CTIO_A64_TYPE;
490         else
491                 prm->pkt->entry_type = CONTINUE_TGT_IO_TYPE;
492
493         prm->pkt->entry_count = (uint8_t) prm->req_cnt;
494         
495         h = q2t_make_handle(prm->tgt->ha);
496         if (h != Q2T_NULL_HANDLE) {
497                 prm->tgt->ha->cmds[h] = prm->cmd;
498         }
499         prm->pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
500
501         timeout = Q2T_TIMEOUT;
502         prm->pkt->timeout = cpu_to_le16(timeout);
503
504         /* Set initiator ID */
505         h = GET_TARGET_ID(prm->tgt->ha, &prm->cmd->atio);
506         SET_TARGET_ID(prm->tgt->ha, prm->pkt->target, h);
507                       
508         prm->pkt->exchange_id = prm->cmd->atio.exchange_id;
509
510         TRACE(TRACE_DEBUG|TRACE_SCSI, 
511               "handle(scst_cmd) -> %08x, timeout %d L %#x -> I %#x E %#x",
512               prm->pkt->handle, timeout, le16_to_cpu(prm->cmd->atio.lun),
513               GET_TARGET_ID(prm->tgt->ha, prm->pkt),
514               le16_to_cpu(prm->pkt->exchange_id));
515
516 }
517
518 static void q2t_load_data_segments(struct q2t_prm *prm)
519 {
520         uint32_t cnt;
521         uint32_t *dword_ptr;
522         int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
523
524         TRACE_DBG("iocb->scsi_status=%x, iocb->flags=%x",
525               le16_to_cpu(prm->pkt->scsi_status), le16_to_cpu(prm->pkt->flags));
526
527         prm->pkt->transfer_length = cpu_to_le32(prm->bufflen);
528
529         /* Setup packet address segment pointer */
530         dword_ptr = prm->pkt->dseg_0_address;
531
532         if (prm->seg_cnt == 0) {
533                 /* No data transfer */
534                 *dword_ptr++ = 0;
535                 *dword_ptr = 0;
536
537                 TRACE_BUFFER("No data, CTIO packet data",
538                              prm->pkt, REQUEST_ENTRY_SIZE);
539                 goto out;
540         }
541
542         /* Set total data segment count */
543         prm->pkt->dseg_count = cpu_to_le16(prm->seg_cnt);
544
545         /* If scatter gather */
546         TRACE(TRACE_SG, "%s", "Building S/G data segments...");
547         /* Load command entry data segments */
548         for (cnt = 0;
549              (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt;
550              cnt++, prm->seg_cnt--) 
551         {
552                 *dword_ptr++ =
553                     cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
554                 if (enable_64bit_addressing) {
555                         *dword_ptr++ =
556                             cpu_to_le32(pci_dma_hi32
557                                         (sg_dma_address(prm->sg)));
558                 }
559                 *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
560
561                 TRACE(TRACE_SG, "S/G Segment phys_addr=%llx:%llx, len=%d",
562                       (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
563                       (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
564                       (int)sg_dma_len(prm->sg));
565
566                 prm->sg++;
567         }
568
569         TRACE_BUFFER("Scatter/gather, CTIO packet data",
570                      prm->pkt, REQUEST_ENTRY_SIZE);
571
572         /* Build continuation packets */
573         while (prm->seg_cnt > 0) {
574                 cont_a64_entry_t *cont_pkt64 = 
575                         (cont_a64_entry_t *)tgt_data.req_cont_pkt(prm->tgt->ha);
576
577                 /* 
578                  * Make sure that from cont_pkt64 none of
579                  * 64-bit specific fields used for 32-bit
580                  * addressing. Cast to (cont_entry_t*) for
581                  * that.
582                  */
583
584                 memset(cont_pkt64, 0, sizeof(*cont_pkt64));
585
586                 cont_pkt64->entry_count = 1;
587                 cont_pkt64->sys_define = 0;
588
589                 if (enable_64bit_addressing) {
590                         cont_pkt64->entry_type = CONTINUE_A64_TYPE;
591                         dword_ptr =
592                             (uint32_t*)&cont_pkt64->dseg_0_address;
593                 } else {
594                         cont_pkt64->entry_type = CONTINUE_TYPE;
595                         dword_ptr =
596                             (uint32_t*)&((cont_entry_t *)
597                                             cont_pkt64)->dseg_0_address;
598                 }
599
600                 /* Load continuation entry data segments */
601                 for (cnt = 0;
602                      cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt;
603                      cnt++, prm->seg_cnt--) 
604                 {
605                         *dword_ptr++ =
606                             cpu_to_le32(pci_dma_lo32
607                                         (sg_dma_address(prm->sg)));
608                         if (enable_64bit_addressing) {
609                                 *dword_ptr++ =
610                                     cpu_to_le32(pci_dma_hi32
611                                                 (sg_dma_address
612                                                  (prm->sg)));
613                         }
614                         *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
615
616                         TRACE(TRACE_SG,
617                               "S/G Segment Cont. phys_addr=%llx:%llx, "
618                               "len=%d",
619                               (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
620                               (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
621                               (int)sg_dma_len(prm->sg));
622
623                         prm->sg++;
624                 }
625
626                 TRACE_BUFFER("Continuation packet data",
627                              cont_pkt64, REQUEST_ENTRY_SIZE);
628         }
629
630 out:
631         return;
632 }
633
634 static void q2t_init_ctio_ret_entry(ctio_ret_entry_t *ctio_m1,
635         struct q2t_prm *prm)
636 {
637         TRACE_ENTRY();
638
639         prm->sense_buffer_len = min((uint32_t)prm->sense_buffer_len, 
640                                     (uint32_t)sizeof(ctio_m1->sense_data));
641
642         ctio_m1->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
643                                                 OF_NO_DATA | OF_SS_MODE_1);
644         ctio_m1->flags |= __constant_cpu_to_le16(OF_INC_RC);
645         ctio_m1->scsi_status = cpu_to_le16(prm->rq_result);
646         ctio_m1->residual = cpu_to_le32(prm->residual);
647         if (SCST_SENSE_VALID(prm->sense_buffer)) {
648                 ctio_m1->scsi_status |=
649                                 __constant_cpu_to_le16(SS_SENSE_LEN_VALID);
650                 ctio_m1->sense_length = cpu_to_le16(prm->sense_buffer_len);
651                 memcpy(ctio_m1->sense_data, prm->sense_buffer,
652                        prm->sense_buffer_len);
653         } else {
654                 memset(ctio_m1->sense_data, 0, sizeof(ctio_m1->sense_data));
655                 ctio_m1->sense_length = 0;
656         }
657
658         TRACE_BUFFER("CTIO returned packet data", ctio_m1, REQUEST_ENTRY_SIZE);
659
660         /* Sense with len > 26, is it possible ??? */
661
662         TRACE_EXIT();
663         return;
664 }
665
666 static inline int q2t_has_data(struct scst_cmd *scst_cmd)
667 {
668         return scst_cmd_get_resp_data_len(scst_cmd) > 0;
669 }
670
671 static int q2t_xmit_response(struct scst_cmd *scst_cmd)
672 {
673         int res = SCST_TGT_RES_SUCCESS;
674         struct q2t_sess *sess;
675         int resp_flags;
676         unsigned long flags = 0;
677         struct q2t_prm prm = { 0 };
678         int data_sense_flag = 0;
679         uint16_t full_req_cnt;
680
681         TRACE_ENTRY();
682         TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd));
683
684         prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
685         sess = (struct q2t_sess *)
686                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
687
688         if (unlikely(scst_cmd_aborted(scst_cmd))) {
689                 scsi_qla_host_t *ha = sess->tgt->ha;
690
691                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): terminating exchange "
692                         "for aborted scst_cmd=%p (tag=%d)",
693                         ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd));
694
695                 prm.cmd->state = Q2T_STATE_ABORTED;
696
697                 q2t_send_term_exchange(ha, prm.cmd, &prm.cmd->atio);
698                 /* !! At this point cmd could be already freed !! */
699                 goto out;
700         }
701
702         prm.sg = scst_cmd_get_sg(scst_cmd);
703         prm.bufflen = scst_cmd_get_resp_data_len(scst_cmd);
704         prm.sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
705         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
706         prm.rq_result = scst_cmd_get_status(scst_cmd);
707         prm.sense_buffer = scst_cmd_get_sense_buffer(scst_cmd);
708         prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
709         prm.tgt = sess->tgt;
710         prm.seg_cnt = 0;
711         prm.req_cnt = 1;
712         resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
713
714         TRACE_DBG("rq_result=%x, resp_flags=%x", prm.rq_result, resp_flags);
715         if (prm.rq_result != 0)
716                 TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
717
718         if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) {
719                 /* ToDo, after it's done in SCST */
720                 PRINT_ERROR("qla2x00tgt(%ld): SCST_TSC_FLAG_STATUS not set: "
721                      "feature not implemented", prm.tgt->ha->instance);
722                 res = SCST_TGT_RES_FATAL_ERROR;
723                 goto out;
724         }
725
726         /* Acquire ring specific lock */
727         spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
728
729         /* Send marker if required */
730         if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
731                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
732                             "failed", prm.tgt->ha->instance);
733                 res = SCST_TGT_RES_FATAL_ERROR;
734                 goto out_unlock;
735         }
736
737         TRACE_DBG("CTIO start: ha(%d)", (int) prm.tgt->ha->instance);
738
739         if (q2t_has_data(scst_cmd)) {
740                 if (q2t_pci_map_calc_cnt(&prm) != 0) {
741                         res = SCST_TGT_RES_QUEUE_FULL;
742                         goto out_unlock;
743                 }
744                 full_req_cnt = prm.req_cnt;
745                 if (SCST_SENSE_VALID(prm.sense_buffer)) {
746                         data_sense_flag = 1;
747                         full_req_cnt++;
748                 }
749         } else
750                 full_req_cnt = prm.req_cnt;
751
752         q2t_build_ctio_pkt(&prm);
753
754         if (prm.data_direction != SCST_DATA_WRITE) {
755                 prm.residual =
756                     le32_to_cpu(prm.cmd->atio.data_length) - prm.bufflen;
757                 if (prm.residual > 0) {
758                         TRACE_DBG("Residual underflow: %d", prm.residual);
759                         prm.rq_result |= SS_RESIDUAL_UNDER;
760                 } else if (prm.residual < 0) {
761                         TRACE_DBG("Residual overflow: %d", prm.residual);
762                         prm.rq_result |= SS_RESIDUAL_OVER;
763                         prm.residual = -prm.residual;
764                 }
765
766                 if (q2t_has_data(scst_cmd)) {
767                         prm.pkt->flags |= __constant_cpu_to_le16(
768                                 OF_FAST_POST | OF_INC_RC | OF_DATA_IN);
769
770                         q2t_load_data_segments(&prm);
771
772                         if (data_sense_flag == 0) {
773                                 prm.pkt->scsi_status = cpu_to_le16(
774                                         prm.rq_result);
775                                 prm.pkt->residual = cpu_to_le32(prm.residual);
776                                 prm.pkt->flags |= 
777                                         __constant_cpu_to_le16(OF_SSTS);
778                         } else {
779                                 ctio_ret_entry_t *ctio_m1 = 
780                                         (ctio_ret_entry_t *)
781                                         tgt_data.req_cont_pkt(prm.tgt->ha);
782
783                                 TRACE_DBG("%s", "Building additional status "
784                                         "packet");
785
786                                 memcpy(ctio_m1, prm.pkt, sizeof(*ctio_m1));
787                                 ctio_m1->entry_count = 1;
788
789                                 /* Real finish is ctio_m1's finish */
790                                 prm.pkt->handle = Q2T_SKIP_HANDLE |
791                                                 CTIO_COMPLETION_HANDLE_MARK;
792
793                                 prm.pkt->flags &= ~__constant_cpu_to_le16(OF_INC_RC);
794
795                                 q2t_init_ctio_ret_entry(ctio_m1, &prm);
796                                 TRACE_BUFFER("Status CTIO packet data", ctio_m1,
797                                         REQUEST_ENTRY_SIZE);
798                         }
799                 } else
800                         q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
801         } else {
802                 q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
803         }
804         
805         prm.cmd->state = Q2T_STATE_PROCESSED;   /* Mid-level is done processing */
806
807         TRACE_BUFFER("Xmitting", prm.pkt, REQUEST_ENTRY_SIZE);
808
809         q2t_exec_queue(prm.tgt->ha);
810
811 out_unlock:
812         /* Release ring specific lock */
813         spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
814
815 out:
816         TRACE_EXIT_RES(res);
817         return res;
818 }
819
820 static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
821 {
822         int res = SCST_TGT_RES_SUCCESS;
823         struct q2t_sess *sess;
824         unsigned long flags = 0;
825         struct q2t_prm prm = { 0 };
826
827         TRACE_ENTRY();
828         TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd));
829
830         prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
831         sess = (struct q2t_sess *)
832                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
833
834         prm.sg = scst_cmd_get_sg(scst_cmd);
835         prm.bufflen = scst_cmd_get_bufflen(scst_cmd);
836         prm.sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
837         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
838         prm.tgt = sess->tgt;
839         prm.req_cnt = 1;
840
841         /* Acquire ring specific lock */
842         spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
843
844         /* Send marker if required */
845         if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
846                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
847                             "failed", prm.tgt->ha->instance);
848                 res = SCST_TGT_RES_FATAL_ERROR;
849                 goto out_unlock;
850         }
851
852         TRACE_DBG("CTIO_start: ha(%d)", (int) prm.tgt->ha->instance);
853
854         /* Calculate number of entries and segments required */
855         if (q2t_pci_map_calc_cnt(&prm) != 0) {
856                 res = SCST_TGT_RES_QUEUE_FULL;
857                 goto out_unlock;
858         }
859
860         prm.cmd->iocb_cnt = prm.req_cnt;
861
862         q2t_build_ctio_pkt(&prm);
863
864         prm.pkt->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_DATA_OUT);
865
866         q2t_load_data_segments(&prm);
867
868         prm.cmd->state = Q2T_STATE_NEED_DATA;
869
870         TRACE_BUFFER("Xfering", prm.pkt, REQUEST_ENTRY_SIZE);
871
872         q2t_exec_queue(prm.tgt->ha);
873         
874 out_unlock:
875         /* Release ring specific lock */
876         spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
877
878         TRACE_EXIT_RES(res);
879         return res;
880 }
881
882 static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
883         atio_entry_t *atio)
884 {
885         ctio_ret_entry_t *ctio;
886         unsigned long flags;
887         int do_tgt_cmd_done = 0;
888
889         TRACE_ENTRY();
890
891         TRACE_DBG("Sending TERM EXCH CTIO (ha=%p)", ha);
892
893         spin_lock_irqsave(&ha->hardware_lock, flags);
894
895         /* Send marker if required */
896         if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
897                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
898                             "failed", ha->instance);
899                 goto out_unlock;
900         }
901
902         ctio = (ctio_ret_entry_t*)tgt_data.req_pkt(ha);
903         if (ctio == NULL) {
904                 PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
905                         "request packet", ha->instance, __func__);
906                 goto out_unlock;
907         }
908
909         ctio->entry_type = CTIO_RET_TYPE;
910         ctio->entry_count = 1;
911
912         if (cmd != NULL) {
913                 ctio->handle = q2t_make_handle(ha);
914                 if (ctio->handle != Q2T_NULL_HANDLE) {
915                         ha->cmds[ctio->handle] = cmd;
916                 } else {
917                         ctio->handle = Q2T_SKIP_HANDLE;
918                         do_tgt_cmd_done = 1;
919                 }
920         } else
921                 ctio->handle = Q2T_SKIP_HANDLE;
922
923         ctio->handle |= CTIO_COMPLETION_HANDLE_MARK;
924
925         SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
926         ctio->exchange_id = atio->exchange_id;
927
928         ctio->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_TERM_EXCH |
929                         OF_NO_DATA | OF_SS_MODE_1);
930         ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
931
932         TRACE_BUFFER("CTIO TERM EXCH packet data", ctio, REQUEST_ENTRY_SIZE);
933
934         q2t_exec_queue(ha);
935
936 out_unlock:
937         spin_unlock_irqrestore(&ha->hardware_lock, flags);
938
939         if (do_tgt_cmd_done) {
940                 msleep(250);
941                 scst_tgt_cmd_done(cmd->scst_cmd);
942                 /* !! At this point cmd could be already freed !! */
943         }
944
945         TRACE_EXIT();
946         return;
947 }
948
949 static inline void q2t_free_cmd(struct q2t_cmd *cmd)
950 {
951         kmem_cache_free(q2t_cmd_cachep, cmd);
952 }
953
954 void q2t_on_free_cmd(struct scst_cmd *scst_cmd)
955 {
956         struct q2t_cmd *cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
957
958         TRACE_ENTRY();
959         TRACE(TRACE_SCSI, "END Command tag %d", scst_cmd_get_tag(scst_cmd));
960
961         scst_cmd_set_tgt_priv(scst_cmd, NULL);
962
963         q2t_free_cmd(cmd);
964
965         TRACE_EXIT();
966         return;
967 }
968
969 /* ha->hardware_lock supposed to be held on entry */
970 static inline struct scst_cmd *q2t_get_cmd(scsi_qla_host_t *ha, uint32_t handle)
971 {
972         if (ha->cmds[handle] != NULL) {
973                 struct scst_cmd *cmd = ha->cmds[handle]->scst_cmd;
974                 ha->cmds[handle] = NULL;
975                 return cmd;
976         } else
977                 return NULL;
978 }
979
980 /* ha->hardware_lock supposed to be held on entry */
981 static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
982                                    uint32_t handle, 
983                                    uint16_t status,
984                                    ctio_common_entry_t *ctio)
985 {
986         struct scst_cmd *scst_cmd;
987         struct q2t_cmd *cmd;
988         uint16_t loop_id = -1;
989
990         TRACE_ENTRY();
991
992         if (ctio != NULL) 
993                 loop_id = GET_TARGET_ID(ha, ctio);
994
995         TRACE(TRACE_DEBUG|TRACE_SCSI, "handle(ctio %p status %#x) <- %08x I %x", 
996               ctio, status, handle, loop_id);
997
998         /* Clear out CTIO_COMPLETION_HANDLE_MARK */
999         handle &= ~CTIO_COMPLETION_HANDLE_MARK;
1000
1001         if (status != CTIO_SUCCESS) {
1002                 switch (status) {
1003                 case CTIO_LIP_RESET:
1004                 case CTIO_TARGET_RESET:
1005                 case CTIO_ABORTED:
1006                 case CTIO_TIMEOUT:
1007                 case CTIO_INVALID_RX_ID:
1008                         /* they are OK */
1009 #if defined(DEBUG) || defined(TRACING)
1010                         PRINT_INFO("qla2x00tgt(%ld): CTIO with status %#x "
1011                                 "received (LIP_RESET=e, ABORTED=2, "
1012                                 "TARGET_RESET=17, TIMEOUT=b, "
1013                                 "INVALID_RX_ID=8)", ha->instance, status);
1014 #endif
1015                         break;
1016
1017                 case CTIO_PORT_LOGGED_OUT:
1018                 case CTIO_PORT_UNAVAILABLE:
1019                         PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED "
1020                                 "OUT (29) or PORT UNAVAILABLE (28) status %x "
1021                                 "received", ha->instance, status);
1022                         break;
1023
1024                 default:
1025                         PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status "
1026                                     "0x%x received", ha->instance, status);
1027                         break;
1028                 }
1029                 q2t_modify_command_count(ha, 1, 0);
1030         }
1031
1032         if (handle != Q2T_NULL_HANDLE) {
1033                 if (unlikely(handle == Q2T_SKIP_HANDLE)) {
1034                         goto out;
1035                 }
1036                 if (unlikely(handle == Q2T_BUSY_HANDLE)) {
1037                         goto out;
1038                 }
1039                 scst_cmd = q2t_get_cmd(ha, handle);
1040                 if (unlikely(scst_cmd == NULL)) {
1041                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1042                                    "find the command with handle %x", 
1043                                    ha->instance, handle);
1044                         goto out;
1045                 }
1046         } else if (ctio != NULL) {
1047                 uint32_t tag = le16_to_cpu(ctio->exchange_id);
1048                 struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1049
1050                 if (sess == NULL) {
1051                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: "
1052                                    "ctio_completion for non-existing session "
1053                                    "(loop_id %d, tag %d)", 
1054                                    ha->instance, loop_id, tag);
1055                         goto out;
1056                 }
1057
1058                 scst_cmd = scst_find_cmd_by_tag(sess->scst_sess, tag);
1059                 if (scst_cmd == NULL) {
1060                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1061                              "find the command with tag %d (loop_id %d)", 
1062                              ha->instance, tag, loop_id);
1063                         goto out;
1064                 }
1065
1066                 TRACE_DBG("Found scst_cmd %p", scst_cmd);
1067         } else
1068                 goto out;
1069
1070         cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1071
1072         if (cmd->state == Q2T_STATE_PROCESSED) {
1073                 TRACE_DBG("Command %p finished", cmd);
1074                 if (q2t_has_data(scst_cmd)) {
1075                         pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1076                                 scst_cmd_get_sg_cnt(scst_cmd),
1077                                 scst_to_tgt_dma_dir(
1078                                         scst_cmd_get_data_direction(scst_cmd)));
1079                 }
1080                 goto out_free;
1081         } else if (cmd->state == Q2T_STATE_NEED_DATA) {
1082                 int context = SCST_CONTEXT_TASKLET;
1083                 int rx_status = SCST_RX_STATUS_SUCCESS;
1084
1085                 cmd->state = Q2T_STATE_DATA_IN;
1086
1087                 if (status != CTIO_SUCCESS)
1088                         rx_status = SCST_RX_STATUS_ERROR;
1089
1090 #ifdef DEBUG_WORK_IN_THREAD
1091                 context = SCST_CONTEXT_THREAD;
1092 #endif
1093
1094                 TRACE_DBG("Data received, context %x, rx_status %d",
1095                       context, rx_status);
1096
1097                 pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1098                         scst_cmd_get_sg_cnt(scst_cmd),
1099                         scst_to_tgt_dma_dir(
1100                                 scst_cmd_get_data_direction(scst_cmd)));
1101
1102                 scst_rx_data(scst_cmd, rx_status, context);
1103         } else if (cmd->state == Q2T_STATE_ABORTED) {
1104                 TRACE_DBG("Aborted command %p finished", cmd);
1105                 goto out_free;
1106         } else {
1107                 PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should "
1108                         "not return a CTIO complete", ha->instance, cmd->state);
1109                 goto out_free;
1110         }
1111
1112 out:
1113         TRACE_EXIT();
1114         return;
1115
1116 out_free:
1117         scst_tgt_cmd_done(scst_cmd);
1118         goto out;
1119 }
1120
1121 /* ha->hardware_lock supposed to be held on entry */
1122 /* called via callback from qla2xxx */
1123 static void q2t_ctio_completion(scsi_qla_host_t *ha, uint32_t handle)
1124 {
1125         TRACE_ENTRY();
1126         BUG_ON(ha == NULL);
1127
1128         if (ha->tgt != NULL) {
1129                 q2t_do_ctio_completion(ha, handle,
1130                                        CTIO_SUCCESS, NULL);
1131         } else {
1132                 TRACE_DBG("CTIO but target mode not enabled. ha %p handle %#x", 
1133                           ha, handle);
1134         }
1135         TRACE_EXIT();
1136         return;
1137 }
1138
1139 /* ha->hardware_lock supposed to be held on entry */
1140 static void q2t_send_busy(scsi_qla_host_t *ha, atio_entry_t *atio)
1141 {
1142         ctio_ret_entry_t *ctio;
1143
1144         TRACE_ENTRY();
1145
1146         ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
1147         ctio->entry_type = CTIO_RET_TYPE;
1148         ctio->entry_count = 1;
1149         ctio->handle = Q2T_BUSY_HANDLE;
1150         ctio->scsi_status = __constant_cpu_to_le16(BUSY << 1);
1151
1152         /* Set IDs */
1153         SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
1154         ctio->exchange_id = atio->exchange_id;
1155
1156         ctio->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
1157                                              OF_NO_DATA | OF_SS_MODE_1);
1158         ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
1159
1160         TRACE_BUFFER("CTIO BUSY packet data", ctio, REQUEST_ENTRY_SIZE);
1161
1162         q2t_exec_queue(ha);
1163
1164         TRACE_EXIT();
1165         return;
1166 }
1167
1168 /* ha->hardware_lock is supposed to be held on entry */
1169 static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
1170 {
1171         int res = 0;
1172         struct q2t_sess *sess = cmd->sess;
1173         uint16_t lun;
1174         scst_data_direction dir = SCST_DATA_NONE;
1175         int context;
1176
1177         TRACE_ENTRY();
1178
1179         /* make it be in network byte order */
1180         lun = swab16(cmd->atio.lun);
1181         cmd->scst_cmd = scst_rx_cmd(sess->scst_sess, (uint8_t *)&lun,
1182                                     sizeof(lun), cmd->atio.cdb, Q2T_MAX_CDB_LEN,
1183                                     SCST_ATOMIC);
1184
1185         if (cmd->scst_cmd == NULL) {
1186                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_cmd() failed for "
1187                      "host %ld(%p)", ha->instance, ha->host_no, ha);
1188                 res = -EFAULT;
1189                 goto out;
1190         }
1191
1192         scst_cmd_set_tag(cmd->scst_cmd, le16_to_cpu(cmd->atio.exchange_id));
1193         scst_cmd_set_tgt_priv(cmd->scst_cmd, cmd);
1194
1195         if (cmd->atio.execution_codes & ATIO_EXEC_READ)
1196                 dir = SCST_DATA_READ;
1197         else if (cmd->atio.execution_codes & ATIO_EXEC_WRITE)
1198                 dir = SCST_DATA_WRITE;
1199         scst_cmd_set_expected(cmd->scst_cmd, dir,
1200                 le32_to_cpu(cmd->atio.data_length));
1201
1202         switch(cmd->atio.task_codes) {
1203         case ATIO_SIMPLE_QUEUE:
1204                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_SIMPLE;
1205                 break;
1206         case ATIO_HEAD_OF_QUEUE:
1207                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE;
1208                 break;
1209         case ATIO_ORDERED_QUEUE:
1210                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1211                 break;
1212         case ATIO_ACA_QUEUE:
1213                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ACA;
1214                 break;
1215         case ATIO_UNTAGGED:
1216                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_UNTAGGED;
1217                 break;
1218         default:
1219                 PRINT_ERROR("qla2x00tgt(%ld): Unknown task code %x, use "
1220                         "ORDERED instead", ha->instance, cmd->atio.task_codes);
1221                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1222                 break;
1223         }
1224
1225 #ifdef DEBUG_WORK_IN_THREAD
1226         context = SCST_CONTEXT_THREAD;
1227 #else
1228         context = SCST_CONTEXT_TASKLET;
1229 #endif
1230
1231         TRACE_DBG("Context %x", context);
1232         TRACE(TRACE_SCSI, "START Command (tag %d)", scst_cmd_get_tag(cmd->scst_cmd));
1233         scst_cmd_init_done(cmd->scst_cmd, context);
1234
1235 out:
1236         TRACE_EXIT_RES(res);
1237         return res;
1238 }
1239
1240 /* Called in SCST's thread context */
1241 static void q2t_alloc_session_done(struct scst_session *scst_sess,
1242                                    void *data, int result)
1243 {
1244         TRACE_ENTRY();
1245
1246         if (result != 0) {
1247                 struct q2t_sess *sess = (struct q2t_sess *)data;
1248                 struct q2t_tgt *tgt = sess->tgt;
1249                 scsi_qla_host_t *ha = tgt->ha;
1250                 unsigned long flags;
1251
1252                 PRINT_INFO("qla2x00tgt(%ld): Session initialization failed",
1253                            ha->instance);
1254
1255                 spin_lock_irqsave(&ha->hardware_lock, flags);
1256                 q2t_unreg_sess(sess);
1257                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1258         }
1259
1260         TRACE_EXIT();
1261         return;
1262 }
1263
1264 static char *q2t_make_name(scsi_qla_host_t *ha, int loop_id)
1265 #ifdef FC_SCST_WWN_AUTH
1266 {
1267         int wwn_found = 0;
1268         char *wwn_str;
1269         fc_port_t *fcl;
1270
1271         wwn_str = kmalloc(2*WWN_SIZE, GFP_ATOMIC);
1272         if (wwn_str == NULL) {
1273                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1274                 goto out;
1275         }
1276
1277         /* Find the WWN in the port db given the loop_id */
1278         list_for_each_entry(fcl, &ha->fcports, list) {
1279             if (loop_id == (fcl->loop_id & 0xFF)) {
1280                 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1281                         fcl->port_name[0], fcl->port_name[1], 
1282                         fcl->port_name[2], fcl->port_name[3], 
1283                         fcl->port_name[4], fcl->port_name[5], 
1284                         fcl->port_name[6], fcl->port_name[7]);
1285                 TRACE_DBG("found wwn: %s for loop_id: %d", wwn_str, loop_id);
1286                 wwn_found = 1;
1287                 break;
1288             }
1289         }
1290
1291         if (wwn_found == 0) {
1292 #if 0
1293                 PRINT_ERROR("qla2x00tgt(%ld): Unable to find wwn login for "
1294                         "loop id %d, using loop id instead", ha->instance, loop_id);
1295                 snprintf(wwn_str, 2*WWN_SIZE, "%d", loop_id);
1296 #else
1297                 TRACE_DBG("qla2x00tgt(%ld): Unable to find wwn login for "
1298                         "loop id %d", ha->instance, loop_id);
1299                 kfree(wwn_str);
1300                 wwn_str = NULL;
1301 #endif
1302         }
1303
1304
1305 out:
1306         return wwn_str;
1307 }
1308 #else
1309 {
1310         char *s;
1311         s = kmalloc(12, GFP_ATOMIC);
1312         if (s != NULL)
1313                 snprintf(s, 12, "%d", loop_id);
1314         return s;
1315 }
1316 #endif
1317
1318 /* ha->hardware_lock supposed to be held on entry */
1319 static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_entry_t *atio)
1320 {
1321         int res = 0;
1322         struct q2t_tgt *tgt;
1323         struct q2t_sess *sess;
1324         struct q2t_cmd *cmd;
1325         uint16_t *pn;
1326         int loop_id;
1327
1328         TRACE_ENTRY();
1329
1330         tgt = ha->tgt;
1331         loop_id = GET_TARGET_ID(ha, atio);
1332
1333         pn = (uint16_t *)(((char *)atio)+0x2a);
1334         TRACE_DBG("To SCST instance=%ld l_id=%d tag=%d wwpn=%04x%04x%04x%04x",
1335                   ha->instance, loop_id, le16_to_cpu(atio->exchange_id),
1336                   le16_to_cpu(pn[0]),
1337                   le16_to_cpu(pn[1]),
1338                   le16_to_cpu(pn[2]),
1339                   le16_to_cpu(pn[3]));
1340         /*        le64_to_cpu(*(uint64_t *)(((char *)atio)+0x2c))); */
1341         /*le32_to_cpu(*(uint32_t *)atio->initiator_port_name)); */
1342
1343
1344         if (tgt->tgt_shutdown) {
1345                 TRACE_DBG("New command while the device %p is shutting down", 
1346                           tgt);
1347                 res = -EFAULT;
1348                 goto out;
1349         }
1350
1351         cmd =  kmem_cache_alloc(q2t_cmd_cachep, GFP_ATOMIC);
1352         if (cmd == NULL) {
1353                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed");
1354                 res = -ENOMEM;
1355                 goto out;
1356         }
1357
1358         TRACE_BUFFER("ATIO Coming Up", atio, sizeof(*atio));
1359         memset(cmd, 0, sizeof(*cmd));
1360         memcpy(&cmd->atio, atio, sizeof(*atio));
1361         cmd->state = Q2T_STATE_NEW;
1362
1363         sess = q2t_find_sess_by_lid(tgt, loop_id);
1364         if (unlikely(sess == NULL)) {
1365                 sess = kzalloc(sizeof(*sess), GFP_ATOMIC);
1366                 if (sess == NULL) {
1367                         TRACE(TRACE_OUT_OF_MEM, "%s",
1368                               "Allocation of sess failed");
1369                         res = -ENOMEM;
1370                         goto out_free_cmd;
1371                 }
1372
1373                 sess->tgt = tgt;
1374                 sess->loop_id = loop_id;
1375                 INIT_LIST_HEAD(&sess->list);
1376
1377                 /* register session (remote initiator) */
1378                 {
1379                         char *name = q2t_make_name(ha, loop_id);
1380                         if (name == NULL) {
1381                                 res = -ESRCH;
1382                                 goto out_free_sess;
1383                         }
1384                         sess->scst_sess = scst_register_session(
1385                                 tgt->scst_tgt, 1, name, sess,
1386                                 q2t_alloc_session_done);
1387                         kfree(name);
1388                 }
1389
1390                 if (sess->scst_sess == NULL) {
1391                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() failed "
1392                              "for host %ld(%p)", ha->instance, ha->host_no, ha);
1393                         res = -EFAULT;
1394                         goto out_free_sess;
1395                 }
1396                 scst_sess_set_tgt_priv(sess->scst_sess, sess);
1397
1398                 /* add session data to host data structure */
1399                 list_add(&sess->list, &tgt->sess_list);
1400                 atomic_inc(&tgt->sess_count);
1401         }
1402
1403         cmd->sess = sess;
1404         res = q2t_do_send_cmd_to_scst(ha, cmd);
1405         if (res != 0)
1406                 goto out_free_cmd;
1407
1408 out:
1409         TRACE_EXIT_RES(res);
1410         return res;
1411
1412 out_free_sess:
1413         kfree(sess);
1414         smp_mb__before_atomic_dec();
1415         if (atomic_dec_and_test(&tgt->sess_count))
1416                 wake_up_all(&tgt->waitQ);
1417         /* go through */
1418
1419 out_free_cmd:
1420         q2t_free_cmd(cmd);
1421         goto out;
1422 }
1423
1424 /* ha->hardware_lock supposed to be held on entry */
1425 static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
1426 {
1427         int res = 0, rc = -1;
1428         struct q2t_mgmt_cmd *mcmd;
1429         struct q2t_tgt *tgt;
1430         struct q2t_sess *sess;
1431         int loop_id;
1432         uint16_t lun;
1433
1434         TRACE_ENTRY();
1435
1436         tgt = ha->tgt;
1437         loop_id = GET_TARGET_ID(ha, iocb);
1438
1439         /* Make it be in network byte order */
1440         lun = swab16(iocb->lun);
1441
1442         sess = q2t_find_sess_by_lid(tgt, loop_id);
1443         if (sess == NULL) {
1444                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task mgmt fn 0x%x for "
1445                       "non-existant session", ha->instance, iocb->task_flags);
1446                 res = -EFAULT;
1447                 goto out;
1448         }
1449
1450         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1451         if (mcmd == NULL) {
1452                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1453                 res = -ENOMEM;
1454                 goto out;
1455         }
1456
1457         mcmd->sess = sess;
1458         mcmd->notify_entry = *iocb;
1459
1460         switch (iocb->task_flags) {
1461         case IMM_NTFY_CLEAR_ACA:
1462                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1463                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1464                                          (uint8_t *)&lun, sizeof(lun), 
1465                                          SCST_ATOMIC, mcmd);
1466                 break;
1467
1468         case IMM_NTFY_TARGET_RESET:
1469                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1470                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1471                                          (uint8_t *)&lun, sizeof(lun), 
1472                                          SCST_ATOMIC, mcmd);
1473                 break;
1474
1475         case IMM_NTFY_LUN_RESET:
1476                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1477                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1478                                          (uint8_t *)&lun, sizeof(lun), 
1479                                          SCST_ATOMIC, mcmd);
1480                 break;
1481
1482         case IMM_NTFY_CLEAR_TS:
1483                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1484                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1485                                          (uint8_t *)&lun, sizeof(lun), 
1486                                          SCST_ATOMIC, mcmd);
1487                 break;
1488
1489         case IMM_NTFY_ABORT_TS:
1490                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1491                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1492                                          (uint8_t *)&lun, sizeof(lun), 
1493                                          SCST_ATOMIC, mcmd);
1494                 break;
1495
1496         default:
1497                 PRINT_ERROR("qla2x00tgt(%ld): Unknown task mgmt fn 0x%x",
1498                             ha->instance, iocb->task_flags);
1499                 break;
1500         }
1501
1502         if (rc != 0) {
1503                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_lun() failed: %d",
1504                             ha->instance, rc);
1505                 res = -EFAULT;
1506                 goto out_free;
1507         }
1508
1509 out:
1510         TRACE_EXIT_RES(res);
1511         return res;
1512
1513 out_free:
1514         kfree(mcmd);
1515         goto out;
1516 }
1517
1518 /* ha->hardware_lock supposed to be held on entry */
1519 static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
1520 {
1521         int res = 0, rc;
1522         struct q2t_mgmt_cmd *mcmd;
1523         struct q2t_sess *sess;
1524         int loop_id;
1525         uint32_t tag;
1526
1527         TRACE_ENTRY();
1528
1529         loop_id = GET_TARGET_ID(ha, iocb);
1530         tag = le16_to_cpu(iocb->seq_id);
1531
1532         sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1533         if (sess == NULL) {
1534                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task abort for unexisting "
1535                         "session", ha->instance);
1536                 res = -EFAULT;
1537                 goto out;
1538         }
1539         
1540         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1541         if (mcmd == NULL) {
1542                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1543                 res = -ENOMEM;
1544                 goto out;
1545         }
1546
1547         mcmd->sess = sess;
1548         mcmd->notify_entry = *iocb;
1549
1550         rc = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, tag, 
1551                 SCST_ATOMIC, mcmd);
1552         if (rc != 0) {
1553                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_tag() failed: %d",
1554                             ha->instance, rc);
1555                 res = -EFAULT;
1556                 goto out_free;
1557         }
1558
1559 out:
1560         TRACE_EXIT_RES(res);
1561         return res;
1562
1563 out_free:
1564         kfree(mcmd);
1565         goto out;
1566 }
1567
1568 /* SCST Callback */
1569 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
1570 {
1571         struct q2t_mgmt_cmd *mcmd;
1572         unsigned long flags;
1573
1574         TRACE_ENTRY();
1575
1576         TRACE(TRACE_MGMT, "scst_mcmd (%p) status %#x state %#x", scst_mcmd, 
1577               scst_mcmd->status, scst_mcmd->state);
1578
1579         mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd);
1580         if (unlikely(mcmd == NULL)) {
1581                 PRINT_ERROR("scst_mcmd %p tgt_spec is NULL", mcmd);
1582                 goto out;
1583         }
1584
1585         spin_lock_irqsave(&mcmd->sess->tgt->ha->hardware_lock, flags);
1586         q2t_send_notify_ack(mcmd->sess->tgt->ha, &mcmd->notify_entry, 0,
1587                 (scst_mgmt_cmd_get_status(scst_mcmd) == SCST_MGMT_STATUS_SUCCESS)
1588                          ? 0 : FC_TM_FAILED, 1);
1589         spin_unlock_irqrestore(&mcmd->sess->tgt->ha->hardware_lock, flags);
1590
1591         /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */
1592         scst_mcmd->tgt_priv = NULL;
1593         kfree(mcmd);
1594
1595 out:
1596         TRACE_EXIT();
1597         return;
1598 }
1599
1600 /* ha->hardware_lock supposed to be held on entry */
1601 static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
1602 {
1603         uint16_t status;
1604         int loop_id;
1605         uint32_t add_flags = 0;
1606         int send_notify_ack = 1;
1607
1608         TRACE_ENTRY();
1609
1610         status = le16_to_cpu(iocb->status);
1611         loop_id = GET_TARGET_ID(ha, iocb);
1612
1613         if (!ha->flags.enable_target_mode || ha->tgt == NULL) {
1614                 TRACE(TRACE_MGMT|TRACE_SCSI|TRACE_DEBUG,
1615                       "Acking %04x S %04x I %#x -> L %#x", status, 
1616                       le16_to_cpu(iocb->seq_id), loop_id,
1617                       le16_to_cpu(iocb->lun));
1618                 goto out;
1619         }
1620
1621         TRACE_BUFFER("IMMED Notify Coming Up", iocb, sizeof(*iocb));
1622         
1623         switch (status) {
1624         case IMM_NTFY_LIP_RESET:
1625                 TRACE(TRACE_MGMT, "LIP reset (I %#x)", loop_id);
1626                 /* 
1627                  * ToDo: doing so we reset all holding RESERVE'ations, 
1628                  * which could be unexpected, so be more carefull here 
1629                  */
1630                 q2t_clear_tgt_db(ha->tgt);
1631                 /* set the Clear LIP reset event flag */
1632                 add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET;
1633                 break;
1634
1635         case IMM_NTFY_IOCB_OVERFLOW:
1636                 PRINT_ERROR("qla2x00tgt(%ld): Cannot provide requested "
1637                         "capability (IOCB overflow)", ha->instance);
1638                 break;
1639
1640         case IMM_NTFY_ABORT_TASK:
1641                 TRACE(TRACE_MGMT, "Abort Task (S %04x I %#x -> L %#x)", 
1642                       le16_to_cpu(iocb->seq_id), loop_id,
1643                       le16_to_cpu(iocb->lun));
1644                 if (q2t_abort_task(ha, iocb) == 0)
1645                         send_notify_ack = 0;
1646                 break;
1647
1648         case IMM_NTFY_PORT_LOGOUT:
1649                 TRACE(TRACE_MGMT, "Port logout (S %04x I %#x -> L %#x)", 
1650                       le16_to_cpu(iocb->seq_id), loop_id,
1651                       le16_to_cpu(iocb->lun));
1652                 /* 
1653                  * ToDo: doing so we reset all holding RESERVE'ations, 
1654                  * which could be unexpected, so be more carefull here 
1655                  */
1656                 q2t_port_logout(ha, loop_id);
1657                 break;
1658
1659         case IMM_NTFY_PORT_CONFIG:
1660         case IMM_NTFY_GLBL_TPRLO:
1661         case IMM_NTFY_GLBL_LOGO:
1662                 /* ToDo: ports DB changes handling ?? */
1663                 TRACE(TRACE_MGMT, "Port config changed, Global TPRLO or "
1664                       "Global LOGO (%d)", status);
1665                 /* 
1666                  * ToDo: doing so we reset all holding RESERVE'ations, 
1667                  * which could be unexpected, so be more carefull here 
1668                  */
1669                 q2t_clear_tgt_db(ha->tgt);
1670                 break;
1671
1672         case IMM_NTFY_RESOURCE:
1673                 PRINT_ERROR("qla2x00tgt(%ld): Out of resources, host %ld",
1674                             ha->instance, ha->host_no);
1675                 break;
1676
1677         case IMM_NTFY_MSG_RX:
1678                 TRACE(TRACE_MGMT, "Immediate notify task %x", iocb->task_flags);
1679                 if (q2t_handle_task_mgmt(ha, iocb) == 0)
1680                         send_notify_ack = 0;
1681                 break;
1682
1683         default:
1684                 PRINT_ERROR("qla2x00tgt(%ld): Received unknown immediate "
1685                         "notify status %x", ha->instance, status);
1686                 break;
1687         }
1688
1689
1690 out:
1691         if (send_notify_ack)
1692                 q2t_send_notify_ack(ha, iocb, add_flags, 0, 0);
1693
1694         TRACE_EXIT();
1695         return;
1696 }
1697
1698 /* ha->hardware_lock supposed to be held on entry */
1699 /* called via callback from qla2xxx */
1700 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
1701 {
1702         atio_entry_t *atio;
1703
1704         TRACE_ENTRY();
1705         
1706         BUG_ON((ha == NULL) || (pkt == NULL));
1707
1708         TRACE(TRACE_SCSI, "pkt %p: T %02x C %02x S %02x handle %#x",
1709               pkt, pkt->entry_type, pkt->entry_count, pkt->entry_status,
1710               pkt->handle);
1711
1712         if (pkt->entry_status != 0) {
1713                 PRINT_ERROR("qla2x00tgt(%ld): Received response packet %x "
1714                      "with error status %x", ha->instance, pkt->entry_type,
1715                      pkt->entry_status);
1716                 goto out;
1717         }
1718
1719         switch (pkt->entry_type) {
1720         case ACCEPT_TGT_IO_TYPE:
1721                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1722                         int rc;
1723                         atio = (atio_entry_t *)pkt;
1724                         TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x "
1725                                   "lun %04x read/write %d data_length %08x "
1726                                   "target_id %02x exchange_id %04x ", 
1727                                   ha->instance, le16_to_cpu(atio->status),
1728                                   le16_to_cpu(atio->lun), 
1729                                   atio->execution_codes,
1730                                   le32_to_cpu(atio->data_length),
1731                                   GET_TARGET_ID(ha, atio),
1732                                   le16_to_cpu(atio->exchange_id));
1733                         if (atio->status !=
1734                                 __constant_cpu_to_le16(ATIO_CDB_VALID)) {
1735                                 PRINT_ERROR("qla2x00tgt(%ld): ATIO with error "
1736                                             "status %x received", ha->instance, 
1737                                             le16_to_cpu(atio->status));
1738                                 break;
1739                         }
1740                         TRACE_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb,
1741                                         sizeof(atio->cdb));
1742                         rc = q2t_send_cmd_to_scst(ha, atio);
1743                         if (unlikely(rc != 0)) {
1744                                 if (rc == -ESRCH) {
1745                                         q2t_send_term_exchange(ha, NULL, atio);
1746                                 } else {
1747                                         PRINT_INFO("qla2x00tgt(%ld): Unable to "
1748                                             "send the command to SCSI target "
1749                                             "mid-level, sending BUSY status", 
1750                                             ha->instance);
1751                                         q2t_send_busy(ha, atio);
1752                                 }
1753                         }
1754                 } else {
1755                         PRINT_ERROR("qla2x00tgt(%ld): ATIO, but target mode "
1756                                 "disabled", ha->instance);
1757                 }
1758                 break;
1759                         
1760         case CONTINUE_TGT_IO_TYPE:
1761                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1762                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1763                         TRACE_DBG("CONTINUE_TGT_IO: instance %ld",
1764                                   ha->instance);
1765                         q2t_do_ctio_completion(ha, entry->handle,
1766                                                le16_to_cpu(entry->status), 
1767                                                entry);
1768                 } else {
1769                         PRINT_ERROR("qla2x00tgt(%ld): CTIO, but target mode "
1770                                 "disabled", ha->instance);
1771                 }
1772                 break;
1773                 
1774         case CTIO_A64_TYPE:
1775                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1776                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1777                         TRACE_DBG("CTIO_A64: instance %ld", ha->instance);
1778                         q2t_do_ctio_completion(ha, entry->handle, 
1779                                                le16_to_cpu(entry->status), 
1780                                                entry);
1781                 } else {
1782                         PRINT_ERROR("qla2x00tgt(%ld): CTIO_A64, but target "
1783                                 "mode disabled", ha->instance);
1784                 }
1785                 break;
1786                         
1787         case IMMED_NOTIFY_TYPE:
1788                 TRACE_DBG("%s", "IMMED_NOTIFY");
1789                 q2t_handle_imm_notify(ha, (notify_entry_t *)pkt);
1790                 break;
1791
1792         case NOTIFY_ACK_TYPE:
1793                 if (ha->tgt == NULL) {
1794                         PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK recieved "
1795                                 "with NULL tgt", ha->instance);
1796                 } else if (ha->tgt->notify_ack_expected > 0) {
1797                         nack_entry_t *entry = (nack_entry_t *)pkt;
1798                         TRACE_DBG("NOTIFY_ACK seq %04x status %x", 
1799                                   le16_to_cpu(entry->seq_id),
1800                                   le16_to_cpu(entry->status));
1801                         ha->tgt->notify_ack_expected--;
1802                         if (entry->status !=
1803                                 __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) {
1804                                 PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK "
1805                                             "failed %x", ha->instance, 
1806                                             le16_to_cpu(entry->status));
1807                         }
1808                 } else {
1809                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected NOTIFY_ACK "
1810                                     "received", ha->instance);
1811                 }
1812                 break;
1813
1814         case MODIFY_LUN_TYPE: 
1815                 if ((ha->tgt != NULL) && (ha->tgt->modify_lun_expected > 0)) {
1816                         struct q2t_tgt *tgt = ha->tgt;
1817                         modify_lun_entry_t *entry = (modify_lun_entry_t *)pkt;
1818                         TRACE_DBG("MODIFY_LUN %x, imm %c%d, cmd %c%d", 
1819                                   entry->status,
1820                                   (entry->operators & MODIFY_LUN_IMM_ADD) ?'+' 
1821                                   :(entry->operators & MODIFY_LUN_IMM_SUB) ?'-' 
1822                                   :' ', 
1823                                   entry->immed_notify_count, 
1824                                   (entry->operators & MODIFY_LUN_CMD_ADD) ?'+' 
1825                                   :(entry->operators & MODIFY_LUN_CMD_SUB) ?'-'
1826                                   :' ', 
1827                                   entry->command_count);
1828                         tgt->modify_lun_expected--;
1829                         if (entry->status != MODIFY_LUN_SUCCESS) {
1830                                 PRINT_ERROR("qla2x00tgt(%ld): MODIFY_LUN "
1831                                             "failed %x", ha->instance, 
1832                                             entry->status);
1833                         }
1834                         tgt->disable_lun_status = entry->status;
1835                         wake_up_all(&tgt->waitQ);
1836
1837                 } else {
1838                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected MODIFY_LUN "
1839                                     "received", (ha != NULL) ?ha->instance :-1);
1840                 }
1841                 break;
1842
1843         case ENABLE_LUN_TYPE:
1844                 if (ha->tgt != NULL) {
1845                         struct q2t_tgt *tgt = ha->tgt;
1846                         elun_entry_t *entry = (elun_entry_t *)pkt;
1847                         TRACE_DBG("ENABLE_LUN %x imm %u cmd %u ", 
1848                                   entry->status, entry->immed_notify_count,
1849                                   entry->command_count);
1850                         if ((ha->flags.enable_target_mode) &&
1851                             (entry->status == ENABLE_LUN_ALREADY_ENABLED)) {
1852                                 TRACE_DBG("LUN is already enabled: %#x",
1853                                           entry->status);
1854                                 entry->status = ENABLE_LUN_SUCCESS;
1855                         } else if (entry->status == ENABLE_LUN_RC_NONZERO) {
1856                                 TRACE_DBG("ENABLE_LUN succeeded but with error: "
1857                                           "%#x", entry->status);
1858                                 entry->status = ENABLE_LUN_SUCCESS;
1859                         } else if (entry->status != ENABLE_LUN_SUCCESS) {
1860                                 PRINT_ERROR("qla2x00tgt(%ld): ENABLE_LUN " 
1861                                             "failed %x", 
1862                                             ha->instance, entry->status);
1863                                 ha->flags.enable_target_mode =
1864                                         ~ha->flags.enable_target_mode;
1865                         } /* else success */
1866                         tgt->disable_lun_status = entry->status;
1867                         wake_up_all(&tgt->waitQ);
1868                 }
1869                 break;
1870
1871         default:
1872                 PRINT_INFO("qla2x00tgt(%ld): Received unknown response pkt "
1873                      "type %x", ha->instance, pkt->entry_type);
1874                 break;
1875         }
1876
1877 out:
1878         TRACE_EXIT();
1879         return;
1880 }
1881
1882 /* ha->hardware_lock supposed to be held on entry */
1883 /* called via callback from qla2xxx */
1884 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha, uint16_t *mailbox)
1885 {
1886         TRACE_ENTRY();
1887
1888         BUG_ON(ha == NULL);
1889
1890         if (ha->tgt == NULL) {
1891                 TRACE(TRACE_DEBUG|TRACE_MGMT, 
1892                       "ASYNC EVENT %#x but no tgt. ha %p tgt_flag %d",
1893                       code, ha, ha->flags.enable_target_mode);
1894                 goto out;
1895         }
1896
1897         switch (code) {
1898         case MBA_RESET:                 /* Reset */
1899         case MBA_SYSTEM_ERR:            /* System Error */
1900         case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
1901         case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
1902         case MBA_LOOP_DOWN:
1903         case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
1904         case MBA_LIP_RESET:             /* LIP reset occurred */
1905         case MBA_POINT_TO_POINT:        /* Point to point mode. */
1906         case MBA_CHG_IN_CONNECTION:     /* Change in connection mode. */
1907                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1908                       "Async event %#x occured: clear tgt_db", code);
1909 #if 0
1910                 /* 
1911                  * ToDo: doing so we reset all holding RESERVE'ations, 
1912                  * which could be unexpected, so be more carefull here 
1913                  */
1914                 q2t_clear_tgt_db(ha->tgt);
1915 #endif
1916                 break;
1917         case MBA_RSCN_UPDATE:
1918                 TRACE(TRACE_MGMT|TRACE_DEBUG, "RSCN Update (%x) N_Port %#06x (fmt %x)",
1919                       code, ((mailbox[1]&0xF)<<2)|le16_to_cpu(mailbox[2]), 
1920                       (mailbox[1]&0xF0)>>1);
1921                 break;
1922
1923         case MBA_PORT_UPDATE:           /* Port database update occurred */
1924                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1925                       "Port DB Chng: L_ID %#4x did %d: ignore",
1926                       le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]));
1927                 break;
1928
1929         case MBA_LOOP_UP:
1930         default:
1931                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1932                       "Async event %#x occured: ignore", code);
1933                 /* just don't DO anything */
1934                 break;
1935         }
1936
1937 out:
1938         TRACE_EXIT();
1939         return;
1940 }
1941
1942 /* no lock held on entry */
1943 /* called via callback from qla2xxx */
1944 static void q2t_host_action(scsi_qla_host_t *ha, 
1945                             qla2x_tgt_host_action_t action)
1946 {
1947         struct q2t_tgt *tgt = NULL;
1948         unsigned long flags = 0;
1949
1950         TRACE_ENTRY();
1951
1952         BUG_ON(ha == NULL);
1953
1954         switch (action) {
1955         case ENABLE_TARGET_MODE :
1956                 tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
1957                 if (tgt == NULL) {
1958                         TRACE(TRACE_OUT_OF_MEM, "%s",
1959                               "Allocation of tgt failed");
1960                         goto out;
1961                 }
1962                 
1963                 tgt->ha = ha;
1964                 tgt->disable_lun_status = Q2T_DISABLE_LUN_STATUS_NOT_SET;
1965                 INIT_LIST_HEAD(&tgt->sess_list);
1966                 atomic_set(&tgt->sess_count, 0);
1967                 init_waitqueue_head(&tgt->waitQ);
1968                 
1969                 if (ha->flags.enable_64bit_addressing) {
1970                         PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
1971                                    "Addressing Enabled", ha->instance);
1972                         tgt->tgt_enable_64bit_addr = 1;
1973                         /* 3 is reserved */
1974                         tgt_template.sg_tablesize = 
1975                                 QLA_MAX_SG64(ha->request_q_length - 3);
1976                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
1977                         tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
1978                 } else {
1979                         PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
1980                                    "PCI Addressing", ha->instance);
1981                         if (tgt_template.sg_tablesize == 0) {
1982                                 tgt_template.sg_tablesize =
1983                                         QLA_MAX_SG32(ha->request_q_length - 3);
1984                         }
1985                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
1986                         tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
1987                 }
1988                 
1989                 tgt->scst_tgt = scst_register(&tgt_template);
1990                 if (!tgt->scst_tgt) {
1991                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
1992                                     "failed for host %ld(%p)", ha->instance, 
1993                                     ha->host_no, ha);
1994                         kfree(tgt);
1995                         goto out;
1996                 }
1997                 
1998                 scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
1999                 
2000                 spin_lock_irqsave(&ha->hardware_lock, flags);
2001                 ha->tgt = tgt;
2002                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2003
2004                 TRACE_DBG("Enable lun for host %ld(%ld,%p)",
2005                           ha->host_no, ha->instance, ha);
2006                 tgt_data.enable_lun(ha);
2007                 
2008                 break;
2009         case DISABLE_TARGET_MODE :
2010                 spin_lock_irqsave(&ha->hardware_lock, flags);
2011                 if (ha->tgt == NULL) {
2012                         /* ensure target mode is marked as off */
2013                         ha->flags.enable_target_mode = 0;
2014                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2015
2016                         if(!ha->flags.host_shutting_down) 
2017                                 tgt_data.disable_lun(ha);
2018                         
2019                         goto out;
2020                 }
2021
2022                 tgt = ha->tgt;
2023                 ha->tgt = NULL; /* ensure no one gets in behind us */
2024                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2025
2026                 TRACE_DBG("Shutting down host %ld(%ld,%p)",
2027                           ha->host_no, ha->instance, ha);
2028                 scst_unregister(tgt->scst_tgt);
2029                 /* free of tgt happens via callback q2t_target_release
2030                  * called from scst_unregister, so we shouldn't touch it again 
2031                  */
2032                 tgt = NULL;
2033                 break;
2034
2035         default :
2036                 printk("%s: Reached default case of enumish switch statment %d",
2037                        __func__, action);
2038         }
2039
2040 out:
2041         TRACE_EXIT();
2042         return;
2043 }
2044
2045 #if defined(DEBUG) || defined(TRACING)
2046
2047 #define Q2T_PROC_LOG_ENTRY_NAME     "trace_level"
2048
2049 #include <linux/proc_fs.h>
2050
2051 static int qla2x00t_proc_log_entry_read(char *buffer, char **start,
2052                                         off_t offset, int length, int *eof,
2053                                         void *data)
2054 {
2055         int res = 0;
2056
2057         TRACE_ENTRY();
2058         res = scst_proc_log_entry_read(buffer, start, offset, length, eof,
2059                                        data, trace_flag, NULL);
2060
2061         TRACE_EXIT_RES(res);
2062         return res;
2063 }
2064
2065 static int qla2x00t_proc_log_entry_write(struct file *file, const char *buf,
2066                                          unsigned long length, void *data)
2067 {
2068         int res = 0;
2069
2070         TRACE_ENTRY();
2071
2072         res = scst_proc_log_entry_write(file, buf, length, data,
2073                         &trace_flag, SCST_DEFAULT_QLA_LOG_FLAGS, NULL);
2074
2075         TRACE_EXIT_RES(res);
2076         return res;
2077 }
2078 #endif
2079
2080 static int qla2x00t_proc_log_entry_build(struct scst_tgt_template *templ)
2081 {
2082         int res = 0;
2083 #if defined(DEBUG) || defined(TRACING)
2084         struct proc_dir_entry *p, *root;
2085
2086         TRACE_ENTRY();
2087         root = scst_proc_get_tgt_root(templ);
2088
2089         if (root) {
2090                 /* create the proc file entry for the device */
2091                 p = create_proc_read_entry(Q2T_PROC_LOG_ENTRY_NAME,
2092                                            S_IFREG | S_IRUGO | S_IWUSR, root,
2093                                            qla2x00t_proc_log_entry_read,
2094                                            (void *)templ->name);
2095                 if (p == NULL) {
2096                         PRINT_ERROR("Not enough memory to register "
2097                              "target driver %s entry %s in /proc",
2098                               templ->name, Q2T_PROC_LOG_ENTRY_NAME);
2099                         res = -ENOMEM;
2100                         goto out;
2101                 }
2102                 p->write_proc = qla2x00t_proc_log_entry_write;
2103         }
2104
2105 out:
2106
2107         TRACE_EXIT_RES(res);
2108 #endif
2109         return res;
2110 }
2111
2112 static void qla2x00t_proc_log_entry_clean(struct scst_tgt_template *templ)
2113 {
2114 #if defined(DEBUG) || defined(TRACING)
2115         struct proc_dir_entry *root;
2116
2117         TRACE_ENTRY();
2118
2119         root = scst_proc_get_tgt_root(templ);
2120
2121         if (root) {
2122                 remove_proc_entry(Q2T_PROC_LOG_ENTRY_NAME, root);
2123         }
2124         TRACE_EXIT();
2125 #endif
2126 }
2127
2128 static int __init qla2x00t_init(void)
2129 {
2130         int res = 0;
2131
2132         TRACE_ENTRY();
2133
2134         q2t_cmd_cachep = kmem_cache_create("q2t_cmd_struct",
2135                                            sizeof(struct q2t_cmd),
2136                                            0, Q2T_CACHE_FLAGS, NULL, NULL);
2137         if (q2t_cmd_cachep == NULL) {
2138                 res = -ENOMEM;
2139                 goto out;
2140         }
2141         
2142         if (scst_register_target_template(&tgt_template) < 0) {
2143                 res = -ENODEV;
2144                 goto out;
2145         }
2146
2147         /* qla2xxx_tgt_register_driver() happens in q2t_target_detect 
2148          * called via scst_register_target_template()
2149          */
2150
2151         res = qla2x00t_proc_log_entry_build(&tgt_template);
2152         if (res < 0) {
2153                 goto out_unreg_target;
2154         }
2155
2156 out:
2157         TRACE_EXIT();
2158         return res;
2159
2160 out_unreg_target:
2161         scst_unregister_target_template(&tgt_template);
2162         qla2xxx_tgt_unregister_driver();
2163         goto out;
2164 }
2165
2166 static void __exit qla2x00t_exit(void)
2167 {
2168         TRACE_ENTRY();
2169
2170         qla2x00t_proc_log_entry_clean(&tgt_template);
2171
2172         scst_unregister_target_template(&tgt_template);
2173         
2174         qla2xxx_tgt_unregister_driver();
2175         
2176         kmem_cache_destroy(q2t_cmd_cachep);
2177
2178         TRACE_EXIT();
2179         return;
2180 }
2181
2182 module_init(qla2x00t_init);
2183 module_exit(qla2x00t_exit);
2184
2185 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar & Nathaniel Clark");
2186 MODULE_DESCRIPTION("Target mode logic for qla2xxx");
2187 MODULE_LICENSE("GPL");
2188 MODULE_VERSION(Q2T_VERSION_STRING);