38e26c13edc11061aceca47927844c60bdecbaa6
[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, int ha_locked);
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, 0);
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, int ha_locked)
884 {
885         ctio_ret_entry_t *ctio;
886         unsigned long flags = 0;
887         int do_tgt_cmd_done = 0;
888
889         TRACE_ENTRY();
890
891         TRACE_DBG("Sending TERM EXCH CTIO (ha=%p)", ha);
892
893         if (!ha_locked)
894                 spin_lock_irqsave(&ha->hardware_lock, flags);
895
896         /* Send marker if required */
897         if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
898                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
899                             "failed", ha->instance);
900                 goto out_unlock;
901         }
902
903         ctio = (ctio_ret_entry_t*)tgt_data.req_pkt(ha);
904         if (ctio == NULL) {
905                 PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
906                         "request packet", ha->instance, __func__);
907                 goto out_unlock;
908         }
909
910         ctio->entry_type = CTIO_RET_TYPE;
911         ctio->entry_count = 1;
912
913         if (cmd != NULL) {
914                 ctio->handle = q2t_make_handle(ha);
915                 if (ctio->handle != Q2T_NULL_HANDLE) {
916                         ha->cmds[ctio->handle] = cmd;
917                 } else {
918                         ctio->handle = Q2T_SKIP_HANDLE;
919                         do_tgt_cmd_done = 1;
920                 }
921         } else
922                 ctio->handle = Q2T_SKIP_HANDLE;
923
924         ctio->handle |= CTIO_COMPLETION_HANDLE_MARK;
925
926         SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
927         ctio->exchange_id = atio->exchange_id;
928
929         ctio->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_TERM_EXCH |
930                         OF_NO_DATA | OF_SS_MODE_1);
931         ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
932
933         TRACE_BUFFER("CTIO TERM EXCH packet data", ctio, REQUEST_ENTRY_SIZE);
934
935         q2t_exec_queue(ha);
936
937 out_unlock:
938         if (!ha_locked)
939                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
940
941         if (do_tgt_cmd_done) {
942                 msleep(250);
943                 scst_tgt_cmd_done(cmd->scst_cmd);
944                 /* !! At this point cmd could be already freed !! */
945         }
946
947         TRACE_EXIT();
948         return;
949 }
950
951 static inline void q2t_free_cmd(struct q2t_cmd *cmd)
952 {
953         kmem_cache_free(q2t_cmd_cachep, cmd);
954 }
955
956 static void q2t_on_free_cmd(struct scst_cmd *scst_cmd)
957 {
958         struct q2t_cmd *cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
959
960         TRACE_ENTRY();
961         TRACE(TRACE_SCSI, "END Command tag %d", scst_cmd_get_tag(scst_cmd));
962
963         scst_cmd_set_tgt_priv(scst_cmd, NULL);
964
965         q2t_free_cmd(cmd);
966
967         TRACE_EXIT();
968         return;
969 }
970
971 /* ha->hardware_lock supposed to be held on entry */
972 static inline struct scst_cmd *q2t_get_cmd(scsi_qla_host_t *ha, uint32_t handle)
973 {
974         if (ha->cmds[handle] != NULL) {
975                 struct scst_cmd *cmd = ha->cmds[handle]->scst_cmd;
976                 ha->cmds[handle] = NULL;
977                 return cmd;
978         } else
979                 return NULL;
980 }
981
982 /* ha->hardware_lock supposed to be held on entry */
983 static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
984                                    uint32_t handle, 
985                                    uint16_t status,
986                                    ctio_common_entry_t *ctio)
987 {
988         struct scst_cmd *scst_cmd;
989         struct q2t_cmd *cmd;
990         uint16_t loop_id = -1;
991
992         TRACE_ENTRY();
993
994         if (ctio != NULL) 
995                 loop_id = GET_TARGET_ID(ha, ctio);
996
997         TRACE(TRACE_DEBUG|TRACE_SCSI, "handle(ctio %p status %#x) <- %08x I %x", 
998               ctio, status, handle, loop_id);
999
1000         /* Clear out CTIO_COMPLETION_HANDLE_MARK */
1001         handle &= ~CTIO_COMPLETION_HANDLE_MARK;
1002
1003         if (status != CTIO_SUCCESS) {
1004                 switch (status) {
1005                 case CTIO_LIP_RESET:
1006                 case CTIO_TARGET_RESET:
1007                 case CTIO_ABORTED:
1008                 case CTIO_TIMEOUT:
1009                 case CTIO_INVALID_RX_ID:
1010                         /* they are OK */
1011 #if defined(DEBUG) || defined(TRACING)
1012                         PRINT_INFO("qla2x00tgt(%ld): CTIO with status %#x "
1013                                 "received (LIP_RESET=e, ABORTED=2, "
1014                                 "TARGET_RESET=17, TIMEOUT=b, "
1015                                 "INVALID_RX_ID=8)", ha->instance, status);
1016 #endif
1017                         break;
1018
1019                 case CTIO_PORT_LOGGED_OUT:
1020                 case CTIO_PORT_UNAVAILABLE:
1021                         PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED "
1022                                 "OUT (29) or PORT UNAVAILABLE (28) status %x "
1023                                 "received", ha->instance, status);
1024                         break;
1025
1026                 default:
1027                         PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status "
1028                                     "0x%x received", ha->instance, status);
1029                         break;
1030                 }
1031                 q2t_modify_command_count(ha, 1, 0);
1032         }
1033
1034         if (handle != Q2T_NULL_HANDLE) {
1035                 if (unlikely(handle == Q2T_SKIP_HANDLE)) {
1036                         goto out;
1037                 }
1038                 if (unlikely(handle == Q2T_BUSY_HANDLE)) {
1039                         goto out;
1040                 }
1041                 scst_cmd = q2t_get_cmd(ha, handle);
1042                 if (unlikely(scst_cmd == NULL)) {
1043                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1044                                    "find the command with handle %x", 
1045                                    ha->instance, handle);
1046                         goto out;
1047                 }
1048         } else if (ctio != NULL) {
1049                 uint32_t tag = le16_to_cpu(ctio->exchange_id);
1050                 struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1051
1052                 if (sess == NULL) {
1053                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: "
1054                                    "ctio_completion for non-existing session "
1055                                    "(loop_id %d, tag %d)", 
1056                                    ha->instance, loop_id, tag);
1057                         goto out;
1058                 }
1059
1060                 scst_cmd = scst_find_cmd_by_tag(sess->scst_sess, tag);
1061                 if (scst_cmd == NULL) {
1062                         PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1063                              "find the command with tag %d (loop_id %d)", 
1064                              ha->instance, tag, loop_id);
1065                         goto out;
1066                 }
1067
1068                 TRACE_DBG("Found scst_cmd %p", scst_cmd);
1069         } else
1070                 goto out;
1071
1072         cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1073
1074         if (cmd->state == Q2T_STATE_PROCESSED) {
1075                 TRACE_DBG("Command %p finished", cmd);
1076                 if (q2t_has_data(scst_cmd)) {
1077                         pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1078                                 scst_cmd_get_sg_cnt(scst_cmd),
1079                                 scst_to_tgt_dma_dir(
1080                                         scst_cmd_get_data_direction(scst_cmd)));
1081                 }
1082                 goto out_free;
1083         } else if (cmd->state == Q2T_STATE_NEED_DATA) {
1084                 int context = SCST_CONTEXT_TASKLET;
1085                 int rx_status = SCST_RX_STATUS_SUCCESS;
1086
1087                 cmd->state = Q2T_STATE_DATA_IN;
1088
1089                 if (status != CTIO_SUCCESS)
1090                         rx_status = SCST_RX_STATUS_ERROR;
1091
1092 #ifdef DEBUG_WORK_IN_THREAD
1093                 context = SCST_CONTEXT_THREAD;
1094 #endif
1095
1096                 TRACE_DBG("Data received, context %x, rx_status %d",
1097                       context, rx_status);
1098
1099                 pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1100                         scst_cmd_get_sg_cnt(scst_cmd),
1101                         scst_to_tgt_dma_dir(
1102                                 scst_cmd_get_data_direction(scst_cmd)));
1103
1104                 scst_rx_data(scst_cmd, rx_status, context);
1105         } else if (cmd->state == Q2T_STATE_ABORTED) {
1106                 TRACE_DBG("Aborted command %p finished", cmd);
1107                 goto out_free;
1108         } else {
1109                 PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should "
1110                         "not return a CTIO complete", ha->instance, cmd->state);
1111                 goto out_free;
1112         }
1113
1114 out:
1115         TRACE_EXIT();
1116         return;
1117
1118 out_free:
1119         scst_tgt_cmd_done(scst_cmd);
1120         goto out;
1121 }
1122
1123 /* ha->hardware_lock supposed to be held on entry */
1124 /* called via callback from qla2xxx */
1125 static void q2t_ctio_completion(scsi_qla_host_t *ha, uint32_t handle)
1126 {
1127         TRACE_ENTRY();
1128         BUG_ON(ha == NULL);
1129
1130         if (ha->tgt != NULL) {
1131                 q2t_do_ctio_completion(ha, handle,
1132                                        CTIO_SUCCESS, NULL);
1133         } else {
1134                 TRACE_DBG("CTIO but target mode not enabled. ha %p handle %#x", 
1135                           ha, handle);
1136         }
1137         TRACE_EXIT();
1138         return;
1139 }
1140
1141 /* ha->hardware_lock supposed to be held on entry */
1142 static void q2t_send_busy(scsi_qla_host_t *ha, atio_entry_t *atio)
1143 {
1144         ctio_ret_entry_t *ctio;
1145
1146         TRACE_ENTRY();
1147
1148         ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
1149         ctio->entry_type = CTIO_RET_TYPE;
1150         ctio->entry_count = 1;
1151         ctio->handle = Q2T_BUSY_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
1152         ctio->scsi_status = __constant_cpu_to_le16(BUSY << 1);
1153
1154         /* Set IDs */
1155         SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
1156         ctio->exchange_id = atio->exchange_id;
1157
1158         ctio->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
1159                                              OF_NO_DATA | OF_SS_MODE_1);
1160         ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
1161
1162         TRACE_BUFFER("CTIO BUSY packet data", ctio, REQUEST_ENTRY_SIZE);
1163
1164         q2t_exec_queue(ha);
1165
1166         TRACE_EXIT();
1167         return;
1168 }
1169
1170 /* ha->hardware_lock is supposed to be held on entry */
1171 static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
1172 {
1173         int res = 0;
1174         struct q2t_sess *sess = cmd->sess;
1175         uint16_t lun;
1176         scst_data_direction dir = SCST_DATA_NONE;
1177         int context;
1178
1179         TRACE_ENTRY();
1180
1181         /* make it be in network byte order */
1182         lun = swab16(cmd->atio.lun);
1183         cmd->scst_cmd = scst_rx_cmd(sess->scst_sess, (uint8_t *)&lun,
1184                                     sizeof(lun), cmd->atio.cdb, Q2T_MAX_CDB_LEN,
1185                                     SCST_ATOMIC);
1186
1187         if (cmd->scst_cmd == NULL) {
1188                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_cmd() failed for "
1189                      "host %ld(%p)", ha->instance, ha->host_no, ha);
1190                 res = -EFAULT;
1191                 goto out;
1192         }
1193
1194         scst_cmd_set_tag(cmd->scst_cmd, le16_to_cpu(cmd->atio.exchange_id));
1195         scst_cmd_set_tgt_priv(cmd->scst_cmd, cmd);
1196
1197         if (cmd->atio.execution_codes & ATIO_EXEC_READ)
1198                 dir = SCST_DATA_READ;
1199         else if (cmd->atio.execution_codes & ATIO_EXEC_WRITE)
1200                 dir = SCST_DATA_WRITE;
1201         scst_cmd_set_expected(cmd->scst_cmd, dir,
1202                 le32_to_cpu(cmd->atio.data_length));
1203
1204         switch(cmd->atio.task_codes) {
1205         case ATIO_SIMPLE_QUEUE:
1206                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_SIMPLE;
1207                 break;
1208         case ATIO_HEAD_OF_QUEUE:
1209                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE;
1210                 break;
1211         case ATIO_ORDERED_QUEUE:
1212                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1213                 break;
1214         case ATIO_ACA_QUEUE:
1215                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ACA;
1216                 break;
1217         case ATIO_UNTAGGED:
1218                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_UNTAGGED;
1219                 break;
1220         default:
1221                 PRINT_ERROR("qla2x00tgt(%ld): Unknown task code %x, use "
1222                         "ORDERED instead", ha->instance, cmd->atio.task_codes);
1223                 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1224                 break;
1225         }
1226
1227 #ifdef DEBUG_WORK_IN_THREAD
1228         context = SCST_CONTEXT_THREAD;
1229 #else
1230         context = SCST_CONTEXT_TASKLET;
1231 #endif
1232
1233         TRACE_DBG("Context %x", context);
1234         TRACE(TRACE_SCSI, "START Command (tag %d)", scst_cmd_get_tag(cmd->scst_cmd));
1235         scst_cmd_init_done(cmd->scst_cmd, context);
1236
1237 out:
1238         TRACE_EXIT_RES(res);
1239         return res;
1240 }
1241
1242 /* Called in SCST's thread context */
1243 static void q2t_alloc_session_done(struct scst_session *scst_sess,
1244                                    void *data, int result)
1245 {
1246         TRACE_ENTRY();
1247
1248         if (result != 0) {
1249                 struct q2t_sess *sess = (struct q2t_sess *)data;
1250                 struct q2t_tgt *tgt = sess->tgt;
1251                 scsi_qla_host_t *ha = tgt->ha;
1252                 unsigned long flags;
1253
1254                 PRINT_INFO("qla2x00tgt(%ld): Session initialization failed",
1255                            ha->instance);
1256
1257                 spin_lock_irqsave(&ha->hardware_lock, flags);
1258                 q2t_unreg_sess(sess);
1259                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1260         }
1261
1262         TRACE_EXIT();
1263         return;
1264 }
1265
1266 static char *q2t_find_name(scsi_qla_host_t *ha, int loop_id)
1267 {
1268         int wwn_found = 0;
1269         char *wwn_str;
1270         fc_port_t *fcl;
1271
1272         wwn_str = kmalloc(2*WWN_SIZE, GFP_ATOMIC);
1273         if (wwn_str == NULL) {
1274                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1275                 goto out;
1276         }
1277
1278         /* Find the WWN in the port db given the loop_id */
1279         list_for_each_entry(fcl, &ha->fcports, list) {
1280             if (loop_id == (fcl->loop_id & 0xFF)) {
1281                 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1282                         fcl->port_name[0], fcl->port_name[1], 
1283                         fcl->port_name[2], fcl->port_name[3], 
1284                         fcl->port_name[4], fcl->port_name[5], 
1285                         fcl->port_name[6], fcl->port_name[7]);
1286                 TRACE_DBG("found wwn: %s for loop_id: %d", wwn_str, loop_id);
1287                 wwn_found = 1;
1288                 break;
1289             }
1290         }
1291
1292         if (wwn_found == 0) {
1293                 TRACE_MGMT_DBG("qla2x00tgt(%ld): Unable to find wwn login for "
1294                         "loop id %d", ha->instance, loop_id);
1295                 kfree(wwn_str);
1296                 wwn_str = NULL;
1297         }
1298
1299 out:
1300         return wwn_str;
1301 }
1302
1303 static char *q2t_make_name(scsi_qla_host_t *ha, const uint8_t *name)
1304 {
1305         char *wwn_str;
1306
1307         wwn_str = kmalloc(3*WWN_SIZE, GFP_ATOMIC);
1308         if (wwn_str == NULL) {
1309                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1310                 goto out;
1311         }
1312         sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1313                 name[1], name[0], name[3], name[2], name[5], name[4], 
1314                 name[7], name[6]);
1315
1316 out:
1317         return wwn_str;
1318 }
1319
1320 /* ha->hardware_lock supposed to be held on entry */
1321 static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_entry_t *atio)
1322 {
1323         int res = 0;
1324         struct q2t_tgt *tgt;
1325         struct q2t_sess *sess;
1326         struct q2t_cmd *cmd;
1327         uint16_t *pn;
1328         int loop_id;
1329
1330         TRACE_ENTRY();
1331
1332         tgt = ha->tgt;
1333         loop_id = GET_TARGET_ID(ha, atio);
1334
1335         pn = (uint16_t *)(((char *)atio)+0x2a);
1336         TRACE_DBG("To SCST instance=%ld l_id=%d tag=%d wwpn=%04x%04x%04x%04x",
1337                   ha->instance, loop_id, le16_to_cpu(atio->exchange_id),
1338                   le16_to_cpu(pn[0]),
1339                   le16_to_cpu(pn[1]),
1340                   le16_to_cpu(pn[2]),
1341                   le16_to_cpu(pn[3]));
1342         /*        le64_to_cpu(*(uint64_t *)(((char *)atio)+0x2c))); */
1343         /*le32_to_cpu(*(uint32_t *)atio->initiator_port_name)); */
1344
1345
1346         if (tgt->tgt_shutdown) {
1347                 TRACE_DBG("New command while the device %p is shutting down", 
1348                           tgt);
1349                 res = -EFAULT;
1350                 goto out;
1351         }
1352
1353         cmd =  kmem_cache_alloc(q2t_cmd_cachep, GFP_ATOMIC);
1354         if (cmd == NULL) {
1355                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed");
1356                 res = -ENOMEM;
1357                 goto out;
1358         }
1359
1360         TRACE_BUFFER("ATIO Coming Up", atio, sizeof(*atio));
1361         memset(cmd, 0, sizeof(*cmd));
1362         memcpy(&cmd->atio, atio, sizeof(*atio));
1363         cmd->state = Q2T_STATE_NEW;
1364
1365         sess = q2t_find_sess_by_lid(tgt, loop_id);
1366         if (unlikely(sess == NULL)) {
1367                 sess = kzalloc(sizeof(*sess), GFP_ATOMIC);
1368                 if (sess == NULL) {
1369                         TRACE(TRACE_OUT_OF_MEM, "%s",
1370                               "Allocation of sess failed");
1371                         res = -ENOMEM;
1372                         goto out_free_cmd;
1373                 }
1374
1375                 sess->tgt = tgt;
1376                 sess->loop_id = loop_id;
1377                 INIT_LIST_HEAD(&sess->list);
1378
1379                 /* register session (remote initiator) */
1380                 {
1381                         char *name;
1382                         if (IS_QLA2200(ha))
1383                                 name = q2t_find_name(ha, loop_id);
1384                         else {
1385                                 name = q2t_make_name(ha,
1386                                         atio->initiator_port_name);
1387                         }
1388                         if (name == NULL) {
1389                                 res = -ESRCH;
1390                                 goto out_free_sess;
1391                         }
1392
1393                         sess->scst_sess = scst_register_session(
1394                                 tgt->scst_tgt, 1, name, sess,
1395                                 q2t_alloc_session_done);
1396                         kfree(name);
1397                 }
1398
1399                 if (sess->scst_sess == NULL) {
1400                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() failed "
1401                              "for host %ld(%p)", ha->instance, ha->host_no, ha);
1402                         res = -EFAULT;
1403                         goto out_free_sess;
1404                 }
1405                 scst_sess_set_tgt_priv(sess->scst_sess, sess);
1406
1407                 /* add session data to host data structure */
1408                 list_add(&sess->list, &tgt->sess_list);
1409                 atomic_inc(&tgt->sess_count);
1410         }
1411
1412         cmd->sess = sess;
1413         res = q2t_do_send_cmd_to_scst(ha, cmd);
1414         if (res != 0)
1415                 goto out_free_cmd;
1416
1417 out:
1418         TRACE_EXIT_RES(res);
1419         return res;
1420
1421 out_free_sess:
1422         kfree(sess);
1423         smp_mb__before_atomic_dec();
1424         if (atomic_dec_and_test(&tgt->sess_count))
1425                 wake_up_all(&tgt->waitQ);
1426         /* go through */
1427
1428 out_free_cmd:
1429         q2t_free_cmd(cmd);
1430         goto out;
1431 }
1432
1433 /* ha->hardware_lock supposed to be held on entry */
1434 static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
1435 {
1436         int res = 0, rc = -1;
1437         struct q2t_mgmt_cmd *mcmd;
1438         struct q2t_tgt *tgt;
1439         struct q2t_sess *sess;
1440         int loop_id;
1441         uint16_t lun;
1442
1443         TRACE_ENTRY();
1444
1445         tgt = ha->tgt;
1446         loop_id = GET_TARGET_ID(ha, iocb);
1447
1448         /* Make it be in network byte order */
1449         lun = swab16(iocb->lun);
1450
1451         sess = q2t_find_sess_by_lid(tgt, loop_id);
1452         if (sess == NULL) {
1453                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task mgmt fn 0x%x for "
1454                       "non-existant session", ha->instance, iocb->task_flags);
1455                 res = -EFAULT;
1456                 goto out;
1457         }
1458
1459         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1460         if (mcmd == NULL) {
1461                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1462                 res = -ENOMEM;
1463                 goto out;
1464         }
1465
1466         mcmd->sess = sess;
1467         mcmd->notify_entry = *iocb;
1468
1469         switch (iocb->task_flags) {
1470         case IMM_NTFY_CLEAR_ACA:
1471                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1472                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1473                                          (uint8_t *)&lun, sizeof(lun), 
1474                                          SCST_ATOMIC, mcmd);
1475                 break;
1476
1477         case IMM_NTFY_TARGET_RESET:
1478                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1479                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1480                                          (uint8_t *)&lun, sizeof(lun), 
1481                                          SCST_ATOMIC, mcmd);
1482                 break;
1483
1484         case IMM_NTFY_LUN_RESET:
1485                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1486                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1487                                          (uint8_t *)&lun, sizeof(lun), 
1488                                          SCST_ATOMIC, mcmd);
1489                 break;
1490
1491         case IMM_NTFY_CLEAR_TS:
1492                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1493                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1494                                          (uint8_t *)&lun, sizeof(lun), 
1495                                          SCST_ATOMIC, mcmd);
1496                 break;
1497
1498         case IMM_NTFY_ABORT_TS:
1499                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1500                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1501                                          (uint8_t *)&lun, sizeof(lun), 
1502                                          SCST_ATOMIC, mcmd);
1503                 break;
1504
1505         default:
1506                 PRINT_ERROR("qla2x00tgt(%ld): Unknown task mgmt fn 0x%x",
1507                             ha->instance, iocb->task_flags);
1508                 break;
1509         }
1510
1511         if (rc != 0) {
1512                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_lun() failed: %d",
1513                             ha->instance, rc);
1514                 res = -EFAULT;
1515                 goto out_free;
1516         }
1517
1518 out:
1519         TRACE_EXIT_RES(res);
1520         return res;
1521
1522 out_free:
1523         kfree(mcmd);
1524         goto out;
1525 }
1526
1527 /* ha->hardware_lock supposed to be held on entry */
1528 static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
1529 {
1530         int res = 0, rc;
1531         struct q2t_mgmt_cmd *mcmd;
1532         struct q2t_sess *sess;
1533         int loop_id;
1534         uint32_t tag;
1535
1536         TRACE_ENTRY();
1537
1538         loop_id = GET_TARGET_ID(ha, iocb);
1539         tag = le16_to_cpu(iocb->seq_id);
1540
1541         sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1542         if (sess == NULL) {
1543                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task abort for unexisting "
1544                         "session", ha->instance);
1545                 res = -EFAULT;
1546                 goto out;
1547         }
1548         
1549         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1550         if (mcmd == NULL) {
1551                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1552                 res = -ENOMEM;
1553                 goto out;
1554         }
1555
1556         mcmd->sess = sess;
1557         mcmd->notify_entry = *iocb;
1558
1559         rc = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, tag, 
1560                 SCST_ATOMIC, mcmd);
1561         if (rc != 0) {
1562                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_tag() failed: %d",
1563                             ha->instance, rc);
1564                 res = -EFAULT;
1565                 goto out_free;
1566         }
1567
1568 out:
1569         TRACE_EXIT_RES(res);
1570         return res;
1571
1572 out_free:
1573         kfree(mcmd);
1574         goto out;
1575 }
1576
1577 /* SCST Callback */
1578 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
1579 {
1580         struct q2t_mgmt_cmd *mcmd;
1581         unsigned long flags;
1582
1583         TRACE_ENTRY();
1584
1585         TRACE(TRACE_MGMT, "scst_mcmd (%p) status %#x state %#x", scst_mcmd, 
1586               scst_mcmd->status, scst_mcmd->state);
1587
1588         mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd);
1589         if (unlikely(mcmd == NULL)) {
1590                 PRINT_ERROR("scst_mcmd %p tgt_spec is NULL", mcmd);
1591                 goto out;
1592         }
1593
1594         spin_lock_irqsave(&mcmd->sess->tgt->ha->hardware_lock, flags);
1595         q2t_send_notify_ack(mcmd->sess->tgt->ha, &mcmd->notify_entry, 0,
1596                 (scst_mgmt_cmd_get_status(scst_mcmd) == SCST_MGMT_STATUS_SUCCESS)
1597                          ? 0 : FC_TM_FAILED, 1);
1598         spin_unlock_irqrestore(&mcmd->sess->tgt->ha->hardware_lock, flags);
1599
1600         /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */
1601         scst_mcmd->tgt_priv = NULL;
1602         kfree(mcmd);
1603
1604 out:
1605         TRACE_EXIT();
1606         return;
1607 }
1608
1609 /* ha->hardware_lock supposed to be held on entry */
1610 static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
1611 {
1612         uint16_t status;
1613         int loop_id;
1614         uint32_t add_flags = 0;
1615         int send_notify_ack = 1;
1616
1617         TRACE_ENTRY();
1618
1619         status = le16_to_cpu(iocb->status);
1620         loop_id = GET_TARGET_ID(ha, iocb);
1621
1622         if (!ha->flags.enable_target_mode || ha->tgt == NULL) {
1623                 TRACE(TRACE_MGMT|TRACE_SCSI|TRACE_DEBUG,
1624                       "Acking %04x S %04x I %#x -> L %#x", status, 
1625                       le16_to_cpu(iocb->seq_id), loop_id,
1626                       le16_to_cpu(iocb->lun));
1627                 goto out;
1628         }
1629
1630         TRACE_BUFFER("IMMED Notify Coming Up", iocb, sizeof(*iocb));
1631         
1632         switch (status) {
1633         case IMM_NTFY_LIP_RESET:
1634                 TRACE(TRACE_MGMT, "LIP reset (I %#x)", loop_id);
1635                 /* 
1636                  * ToDo: doing so we reset all holding RESERVE'ations, 
1637                  * which could be unexpected, so be more carefull here 
1638                  */
1639                 q2t_clear_tgt_db(ha->tgt);
1640                 /* set the Clear LIP reset event flag */
1641                 add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET;
1642                 break;
1643
1644         case IMM_NTFY_IOCB_OVERFLOW:
1645                 PRINT_ERROR("qla2x00tgt(%ld): Cannot provide requested "
1646                         "capability (IOCB overflow)", ha->instance);
1647                 break;
1648
1649         case IMM_NTFY_ABORT_TASK:
1650                 TRACE(TRACE_MGMT, "Abort Task (S %04x I %#x -> L %#x)", 
1651                       le16_to_cpu(iocb->seq_id), loop_id,
1652                       le16_to_cpu(iocb->lun));
1653                 if (q2t_abort_task(ha, iocb) == 0)
1654                         send_notify_ack = 0;
1655                 break;
1656
1657         case IMM_NTFY_PORT_LOGOUT:
1658                 TRACE(TRACE_MGMT, "Port logout (S %04x I %#x -> L %#x)", 
1659                       le16_to_cpu(iocb->seq_id), loop_id,
1660                       le16_to_cpu(iocb->lun));
1661                 /* 
1662                  * ToDo: doing so we reset all holding RESERVE'ations, 
1663                  * which could be unexpected, so be more carefull here 
1664                  */
1665                 q2t_port_logout(ha, loop_id);
1666                 break;
1667
1668         case IMM_NTFY_PORT_CONFIG:
1669         case IMM_NTFY_GLBL_TPRLO:
1670         case IMM_NTFY_GLBL_LOGO:
1671                 /* ToDo: ports DB changes handling ?? */
1672                 TRACE(TRACE_MGMT, "Port config changed, Global TPRLO or "
1673                       "Global LOGO (%d)", status);
1674                 /* 
1675                  * ToDo: doing so we reset all holding RESERVE'ations, 
1676                  * which could be unexpected, so be more carefull here 
1677                  */
1678                 q2t_clear_tgt_db(ha->tgt);
1679                 break;
1680
1681         case IMM_NTFY_RESOURCE:
1682                 PRINT_ERROR("qla2x00tgt(%ld): Out of resources, host %ld",
1683                             ha->instance, ha->host_no);
1684                 break;
1685
1686         case IMM_NTFY_MSG_RX:
1687                 TRACE(TRACE_MGMT, "Immediate notify task %x", iocb->task_flags);
1688                 if (q2t_handle_task_mgmt(ha, iocb) == 0)
1689                         send_notify_ack = 0;
1690                 break;
1691
1692         default:
1693                 PRINT_ERROR("qla2x00tgt(%ld): Received unknown immediate "
1694                         "notify status %x", ha->instance, status);
1695                 break;
1696         }
1697
1698
1699 out:
1700         if (send_notify_ack)
1701                 q2t_send_notify_ack(ha, iocb, add_flags, 0, 0);
1702
1703         TRACE_EXIT();
1704         return;
1705 }
1706
1707 /* ha->hardware_lock supposed to be held on entry */
1708 /* called via callback from qla2xxx */
1709 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
1710 {
1711         atio_entry_t *atio;
1712
1713         TRACE_ENTRY();
1714         
1715         BUG_ON((ha == NULL) || (pkt == NULL));
1716
1717         TRACE(TRACE_SCSI, "pkt %p: T %02x C %02x S %02x handle %#x",
1718               pkt, pkt->entry_type, pkt->entry_count, pkt->entry_status,
1719               pkt->handle);
1720
1721         if (pkt->entry_status != 0) {
1722                 PRINT_ERROR("qla2x00tgt(%ld): Received response packet %x "
1723                      "with error status %x", ha->instance, pkt->entry_type,
1724                      pkt->entry_status);
1725                 goto out;
1726         }
1727
1728         switch (pkt->entry_type) {
1729         case ACCEPT_TGT_IO_TYPE:
1730                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1731                         int rc;
1732                         atio = (atio_entry_t *)pkt;
1733                         TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x "
1734                                   "lun %04x read/write %d data_length %08x "
1735                                   "target_id %02x exchange_id %04x ", 
1736                                   ha->instance, le16_to_cpu(atio->status),
1737                                   le16_to_cpu(atio->lun), 
1738                                   atio->execution_codes,
1739                                   le32_to_cpu(atio->data_length),
1740                                   GET_TARGET_ID(ha, atio),
1741                                   le16_to_cpu(atio->exchange_id));
1742                         if (atio->status !=
1743                                 __constant_cpu_to_le16(ATIO_CDB_VALID)) {
1744                                 PRINT_ERROR("qla2x00tgt(%ld): ATIO with error "
1745                                             "status %x received", ha->instance, 
1746                                             le16_to_cpu(atio->status));
1747                                 break;
1748                         }
1749                         TRACE_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb,
1750                                         sizeof(atio->cdb));
1751                         rc = q2t_send_cmd_to_scst(ha, atio);
1752                         if (unlikely(rc != 0)) {
1753                                 if (rc == -ESRCH) {
1754 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
1755                                         q2t_send_busy(ha, atio);
1756 #else
1757                                         q2t_send_term_exchange(ha, NULL, atio, 1);
1758 #endif
1759                                 } else {
1760                                         PRINT_INFO("qla2x00tgt(%ld): Unable to "
1761                                             "send the command to SCSI target "
1762                                             "mid-level, sending BUSY status", 
1763                                             ha->instance);
1764                                         q2t_send_busy(ha, atio);
1765                                 }
1766                         }
1767                 } else {
1768                         PRINT_ERROR("qla2x00tgt(%ld): ATIO, but target mode "
1769                                 "disabled", ha->instance);
1770                 }
1771                 break;
1772                         
1773         case CONTINUE_TGT_IO_TYPE:
1774                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1775                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1776                         TRACE_DBG("CONTINUE_TGT_IO: instance %ld",
1777                                   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, but target mode "
1783                                 "disabled", ha->instance);
1784                 }
1785                 break;
1786                 
1787         case CTIO_A64_TYPE:
1788                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1789                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1790                         TRACE_DBG("CTIO_A64: instance %ld", ha->instance);
1791                         q2t_do_ctio_completion(ha, entry->handle, 
1792                                                le16_to_cpu(entry->status), 
1793                                                entry);
1794                 } else {
1795                         PRINT_ERROR("qla2x00tgt(%ld): CTIO_A64, but target "
1796                                 "mode disabled", ha->instance);
1797                 }
1798                 break;
1799                         
1800         case IMMED_NOTIFY_TYPE:
1801                 TRACE_DBG("%s", "IMMED_NOTIFY");
1802                 q2t_handle_imm_notify(ha, (notify_entry_t *)pkt);
1803                 break;
1804
1805         case NOTIFY_ACK_TYPE:
1806                 if (ha->tgt == NULL) {
1807                         PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK recieved "
1808                                 "with NULL tgt", ha->instance);
1809                 } else if (ha->tgt->notify_ack_expected > 0) {
1810                         nack_entry_t *entry = (nack_entry_t *)pkt;
1811                         TRACE_DBG("NOTIFY_ACK seq %04x status %x", 
1812                                   le16_to_cpu(entry->seq_id),
1813                                   le16_to_cpu(entry->status));
1814                         ha->tgt->notify_ack_expected--;
1815                         if (entry->status !=
1816                                 __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) {
1817                                 PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK "
1818                                             "failed %x", ha->instance, 
1819                                             le16_to_cpu(entry->status));
1820                         }
1821                 } else {
1822                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected NOTIFY_ACK "
1823                                     "received", ha->instance);
1824                 }
1825                 break;
1826
1827         case MODIFY_LUN_TYPE: 
1828                 if ((ha->tgt != NULL) && (ha->tgt->modify_lun_expected > 0)) {
1829                         struct q2t_tgt *tgt = ha->tgt;
1830                         modify_lun_entry_t *entry = (modify_lun_entry_t *)pkt;
1831                         TRACE_DBG("MODIFY_LUN %x, imm %c%d, cmd %c%d", 
1832                                   entry->status,
1833                                   (entry->operators & MODIFY_LUN_IMM_ADD) ?'+' 
1834                                   :(entry->operators & MODIFY_LUN_IMM_SUB) ?'-' 
1835                                   :' ', 
1836                                   entry->immed_notify_count, 
1837                                   (entry->operators & MODIFY_LUN_CMD_ADD) ?'+' 
1838                                   :(entry->operators & MODIFY_LUN_CMD_SUB) ?'-'
1839                                   :' ', 
1840                                   entry->command_count);
1841                         tgt->modify_lun_expected--;
1842                         if (entry->status != MODIFY_LUN_SUCCESS) {
1843                                 PRINT_ERROR("qla2x00tgt(%ld): MODIFY_LUN "
1844                                             "failed %x", ha->instance, 
1845                                             entry->status);
1846                         }
1847                         tgt->disable_lun_status = entry->status;
1848                         wake_up_all(&tgt->waitQ);
1849
1850                 } else {
1851                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected MODIFY_LUN "
1852                                     "received", (ha != NULL) ?ha->instance :-1);
1853                 }
1854                 break;
1855
1856         case ENABLE_LUN_TYPE:
1857                 if (ha->tgt != NULL) {
1858                         struct q2t_tgt *tgt = ha->tgt;
1859                         elun_entry_t *entry = (elun_entry_t *)pkt;
1860                         TRACE_DBG("ENABLE_LUN %x imm %u cmd %u ", 
1861                                   entry->status, entry->immed_notify_count,
1862                                   entry->command_count);
1863                         if ((ha->flags.enable_target_mode) &&
1864                             (entry->status == ENABLE_LUN_ALREADY_ENABLED)) {
1865                                 TRACE_DBG("LUN is already enabled: %#x",
1866                                           entry->status);
1867                                 entry->status = ENABLE_LUN_SUCCESS;
1868                         } else if (entry->status == ENABLE_LUN_RC_NONZERO) {
1869                                 TRACE_DBG("ENABLE_LUN succeeded but with error: "
1870                                           "%#x", entry->status);
1871                                 entry->status = ENABLE_LUN_SUCCESS;
1872                         } else if (entry->status != ENABLE_LUN_SUCCESS) {
1873                                 PRINT_ERROR("qla2x00tgt(%ld): ENABLE_LUN " 
1874                                             "failed %x", 
1875                                             ha->instance, entry->status);
1876                                 ha->flags.enable_target_mode =
1877                                         ~ha->flags.enable_target_mode;
1878                         } /* else success */
1879                         tgt->disable_lun_status = entry->status;
1880                         wake_up_all(&tgt->waitQ);
1881                 }
1882                 break;
1883
1884         default:
1885                 PRINT_INFO("qla2x00tgt(%ld): Received unknown response pkt "
1886                      "type %x", ha->instance, pkt->entry_type);
1887                 break;
1888         }
1889
1890 out:
1891         TRACE_EXIT();
1892         return;
1893 }
1894
1895 /* ha->hardware_lock supposed to be held on entry */
1896 /* called via callback from qla2xxx */
1897 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha, uint16_t *mailbox)
1898 {
1899         TRACE_ENTRY();
1900
1901         BUG_ON(ha == NULL);
1902
1903         if (ha->tgt == NULL) {
1904                 TRACE(TRACE_DEBUG|TRACE_MGMT, 
1905                       "ASYNC EVENT %#x but no tgt. ha %p tgt_flag %d",
1906                       code, ha, ha->flags.enable_target_mode);
1907                 goto out;
1908         }
1909
1910         switch (code) {
1911         case MBA_RESET:                 /* Reset */
1912         case MBA_SYSTEM_ERR:            /* System Error */
1913         case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
1914         case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
1915         case MBA_LOOP_DOWN:
1916         case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
1917         case MBA_LIP_RESET:             /* LIP reset occurred */
1918         case MBA_POINT_TO_POINT:        /* Point to point mode. */
1919         case MBA_CHG_IN_CONNECTION:     /* Change in connection mode. */
1920                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1921                       "Async event %#x occured: clear tgt_db", code);
1922 #if 0
1923                 /* 
1924                  * ToDo: doing so we reset all holding RESERVE'ations, 
1925                  * which could be unexpected, so be more carefull here 
1926                  */
1927                 q2t_clear_tgt_db(ha->tgt);
1928 #endif
1929                 break;
1930         case MBA_RSCN_UPDATE:
1931                 TRACE(TRACE_MGMT|TRACE_DEBUG, "RSCN Update (%x) N_Port %#06x (fmt %x)",
1932                       code, ((mailbox[1]&0xF)<<2)|le16_to_cpu(mailbox[2]), 
1933                       (mailbox[1]&0xF0)>>1);
1934                 break;
1935
1936         case MBA_PORT_UPDATE:           /* Port database update occurred */
1937                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1938                       "Port DB Chng: L_ID %#4x did %d: ignore",
1939                       le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]));
1940                 break;
1941
1942         case MBA_LOOP_UP:
1943         default:
1944                 TRACE(TRACE_MGMT|TRACE_DEBUG,
1945                       "Async event %#x occured: ignore", code);
1946                 /* just don't DO anything */
1947                 break;
1948         }
1949
1950 out:
1951         TRACE_EXIT();
1952         return;
1953 }
1954
1955 /* no lock held on entry */
1956 /* called via callback from qla2xxx */
1957 static void q2t_host_action(scsi_qla_host_t *ha, 
1958                             qla2x_tgt_host_action_t action)
1959 {
1960         struct q2t_tgt *tgt = NULL;
1961         unsigned long flags = 0;
1962
1963         TRACE_ENTRY();
1964
1965         BUG_ON(ha == NULL);
1966
1967         switch (action) {
1968         case ENABLE_TARGET_MODE :
1969                 tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
1970                 if (tgt == NULL) {
1971                         TRACE(TRACE_OUT_OF_MEM, "%s",
1972                               "Allocation of tgt failed");
1973                         goto out;
1974                 }
1975                 
1976                 tgt->ha = ha;
1977                 tgt->disable_lun_status = Q2T_DISABLE_LUN_STATUS_NOT_SET;
1978                 INIT_LIST_HEAD(&tgt->sess_list);
1979                 atomic_set(&tgt->sess_count, 0);
1980                 init_waitqueue_head(&tgt->waitQ);
1981                 
1982                 if (ha->flags.enable_64bit_addressing) {
1983                         PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
1984                                    "Addressing Enabled", ha->instance);
1985                         tgt->tgt_enable_64bit_addr = 1;
1986                         /* 3 is reserved */
1987                         tgt_template.sg_tablesize = 
1988                                 QLA_MAX_SG64(ha->request_q_length - 3);
1989                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
1990                         tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
1991                 } else {
1992                         PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
1993                                    "PCI Addressing", ha->instance);
1994                         if (tgt_template.sg_tablesize == 0) {
1995                                 tgt_template.sg_tablesize =
1996                                         QLA_MAX_SG32(ha->request_q_length - 3);
1997                         }
1998                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
1999                         tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
2000                 }
2001                 
2002                 tgt->scst_tgt = scst_register(&tgt_template);
2003                 if (!tgt->scst_tgt) {
2004                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
2005                                     "failed for host %ld(%p)", ha->instance, 
2006                                     ha->host_no, ha);
2007                         kfree(tgt);
2008                         goto out;
2009                 }
2010                 
2011                 scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
2012                 
2013                 spin_lock_irqsave(&ha->hardware_lock, flags);
2014                 ha->tgt = tgt;
2015                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2016
2017                 TRACE_DBG("Enable lun for host %ld(%ld,%p)",
2018                           ha->host_no, ha->instance, ha);
2019                 tgt_data.enable_lun(ha);
2020                 
2021                 break;
2022         case DISABLE_TARGET_MODE :
2023                 spin_lock_irqsave(&ha->hardware_lock, flags);
2024                 if (ha->tgt == NULL) {
2025                         /* ensure target mode is marked as off */
2026                         ha->flags.enable_target_mode = 0;
2027                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2028
2029                         if(!ha->flags.host_shutting_down) 
2030                                 tgt_data.disable_lun(ha);
2031                         
2032                         goto out;
2033                 }
2034
2035                 tgt = ha->tgt;
2036                 ha->tgt = NULL; /* ensure no one gets in behind us */
2037                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2038
2039                 TRACE_DBG("Shutting down host %ld(%ld,%p)",
2040                           ha->host_no, ha->instance, ha);
2041                 scst_unregister(tgt->scst_tgt);
2042                 /* free of tgt happens via callback q2t_target_release
2043                  * called from scst_unregister, so we shouldn't touch it again 
2044                  */
2045                 tgt = NULL;
2046                 break;
2047
2048         default :
2049                 printk("%s: Reached default case of enumish switch statment %d",
2050                        __func__, action);
2051         }
2052
2053 out:
2054         TRACE_EXIT();
2055         return;
2056 }
2057
2058 #if defined(DEBUG) || defined(TRACING)
2059
2060 #define Q2T_PROC_LOG_ENTRY_NAME     "trace_level"
2061
2062 #include <linux/proc_fs.h>
2063
2064 static int qla2x00t_proc_log_entry_read(char *buffer, char **start,
2065                                         off_t offset, int length, int *eof,
2066                                         void *data)
2067 {
2068         int res = 0;
2069
2070         TRACE_ENTRY();
2071         res = scst_proc_log_entry_read(buffer, start, offset, length, eof,
2072                                        data, trace_flag, NULL);
2073
2074         TRACE_EXIT_RES(res);
2075         return res;
2076 }
2077
2078 static int qla2x00t_proc_log_entry_write(struct file *file, const char *buf,
2079                                          unsigned long length, void *data)
2080 {
2081         int res = 0;
2082
2083         TRACE_ENTRY();
2084
2085         res = scst_proc_log_entry_write(file, buf, length, data,
2086                         &trace_flag, SCST_DEFAULT_QLA_LOG_FLAGS, NULL);
2087
2088         TRACE_EXIT_RES(res);
2089         return res;
2090 }
2091 #endif
2092
2093 static int qla2x00t_proc_log_entry_build(struct scst_tgt_template *templ)
2094 {
2095         int res = 0;
2096 #if defined(DEBUG) || defined(TRACING)
2097         struct proc_dir_entry *p, *root;
2098
2099         TRACE_ENTRY();
2100         root = scst_proc_get_tgt_root(templ);
2101
2102         if (root) {
2103                 /* create the proc file entry for the device */
2104                 p = create_proc_read_entry(Q2T_PROC_LOG_ENTRY_NAME,
2105                                            S_IFREG | S_IRUGO | S_IWUSR, root,
2106                                            qla2x00t_proc_log_entry_read,
2107                                            (void *)templ->name);
2108                 if (p == NULL) {
2109                         PRINT_ERROR("Not enough memory to register "
2110                              "target driver %s entry %s in /proc",
2111                               templ->name, Q2T_PROC_LOG_ENTRY_NAME);
2112                         res = -ENOMEM;
2113                         goto out;
2114                 }
2115                 p->write_proc = qla2x00t_proc_log_entry_write;
2116         }
2117
2118 out:
2119
2120         TRACE_EXIT_RES(res);
2121 #endif
2122         return res;
2123 }
2124
2125 static void qla2x00t_proc_log_entry_clean(struct scst_tgt_template *templ)
2126 {
2127 #if defined(DEBUG) || defined(TRACING)
2128         struct proc_dir_entry *root;
2129
2130         TRACE_ENTRY();
2131
2132         root = scst_proc_get_tgt_root(templ);
2133
2134         if (root) {
2135                 remove_proc_entry(Q2T_PROC_LOG_ENTRY_NAME, root);
2136         }
2137         TRACE_EXIT();
2138 #endif
2139 }
2140
2141 static int __init qla2x00t_init(void)
2142 {
2143         int res = 0;
2144
2145         TRACE_ENTRY();
2146
2147         q2t_cmd_cachep = kmem_cache_create("q2t_cmd_struct",
2148                                            sizeof(struct q2t_cmd),
2149                                            0, Q2T_CACHE_FLAGS, NULL, NULL);
2150         if (q2t_cmd_cachep == NULL) {
2151                 res = -ENOMEM;
2152                 goto out;
2153         }
2154         
2155         if (scst_register_target_template(&tgt_template) < 0) {
2156                 res = -ENODEV;
2157                 goto out;
2158         }
2159
2160         /* qla2xxx_tgt_register_driver() happens in q2t_target_detect 
2161          * called via scst_register_target_template()
2162          */
2163
2164         res = qla2x00t_proc_log_entry_build(&tgt_template);
2165         if (res < 0) {
2166                 goto out_unreg_target;
2167         }
2168
2169 out:
2170         TRACE_EXIT();
2171         return res;
2172
2173 out_unreg_target:
2174         scst_unregister_target_template(&tgt_template);
2175         qla2xxx_tgt_unregister_driver();
2176         goto out;
2177 }
2178
2179 static void __exit qla2x00t_exit(void)
2180 {
2181         TRACE_ENTRY();
2182
2183         qla2x00t_proc_log_entry_clean(&tgt_template);
2184
2185         scst_unregister_target_template(&tgt_template);
2186         
2187         qla2xxx_tgt_unregister_driver();
2188         
2189         kmem_cache_destroy(q2t_cmd_cachep);
2190
2191         TRACE_EXIT();
2192         return;
2193 }
2194
2195 module_init(qla2x00t_init);
2196 module_exit(qla2x00t_exit);
2197
2198 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar & Nathaniel Clark");
2199 MODULE_DESCRIPTION("Target mode logic for qla2xxx");
2200 MODULE_LICENSE("GPL");
2201 MODULE_VERSION(Q2T_VERSION_STRING);