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, 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_MGMT_DBG("tgt->handle %x empty(sess_list) %d sess_count %d",
296               tgt->handle, list_empty(&tgt->sess_list),
297               atomic_read(&tgt->sess_count));
298
299         smp_mb__before_atomic_dec();
300         if (atomic_dec_and_test(&tgt->sess_count)) {
301                 smp_mb__after_atomic_dec();
302                 wake_up_all(&tgt->waitQ);
303         }
304
305 out:
306         TRACE_EXIT();
307         return;
308 }
309
310 /* ha->hardware_lock supposed to be held on entry */
311 static void q2t_unreg_sess(struct q2t_sess *sess)
312 {
313         TRACE_ENTRY();
314
315         if (sess == NULL)
316                 goto out;
317
318         list_del(&sess->list);
319
320         PRINT_INFO("qla2x00tgt(%ld): session for loop_id %d deleted",
321                 sess->tgt->ha->instance, sess->loop_id);
322
323         /* 
324          * Any commands for this session will be finished regularly,
325          * because we must not drop SCSI commands on transport level,
326          * at least without any response to the initiator.
327          */
328
329         scst_unregister_session(sess->scst_sess, 0, q2t_free_session_done);
330
331 out:
332         TRACE_EXIT();
333         return;
334 }
335
336 /* ha->hardware_lock supposed to be held on entry */
337 static void q2t_port_logout(scsi_qla_host_t *ha, int loop_id)
338 {
339         struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
340
341         TRACE_MGMT_DBG("scsi(%ld) Unregistering session %p loop_id=%d",
342               ha->host_no, sess, loop_id);
343
344         q2t_unreg_sess(sess);
345 }
346
347 /* ha->hardware_lock supposed to be held on entry */
348 static void q2t_clear_tgt_db(struct q2t_tgt *tgt)
349 {
350         struct q2t_sess *sess, *sess_tmp;
351
352         TRACE_ENTRY();
353
354         TRACE_MGMT_DBG("Clearing targets DB %p", tgt);
355
356         list_for_each_entry_safe(sess, sess_tmp, &tgt->sess_list, list) {
357                 q2t_unreg_sess(sess);
358         }
359
360         /* At this point tgt could be already dead */
361
362         TRACE_MGMT_DBG("Finished clearing Target DB %p", tgt);
363
364         TRACE_EXIT();
365         return;
366 }
367
368 /* should be called w/out hardware_lock, but tgt should be
369  * unfindable at this point */
370 static int q2t_target_release(struct scst_tgt *scst_tgt)
371 {
372         int res = 0;
373         struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
374         scsi_qla_host_t *ha = tgt->ha;
375         unsigned long flags = 0;
376
377         TRACE_ENTRY();
378
379         spin_lock_irqsave(&ha->hardware_lock, flags);
380         tgt->tgt_shutdown = 1;
381         q2t_clear_tgt_db(tgt);
382         spin_unlock_irqrestore(&ha->hardware_lock, flags);
383
384         wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha));
385
386         /* big hammer */
387         if(!ha->flags.host_shutting_down) 
388                 tgt_data.disable_lun(ha);
389
390         /* wait for sessions to clear out (just in case) */
391         wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha)); 
392         
393         TRACE_MGMT_DBG("Finished waiting for tgt %p: empty(sess_list)=%d "
394                 "sess_count=%d", tgt, list_empty(&tgt->sess_list),
395                 atomic_read(&tgt->sess_count));
396
397         scst_tgt_set_tgt_priv(scst_tgt, NULL);
398
399         kfree(tgt);
400
401         TRACE_EXIT_RES(res);
402         return res;
403 }
404
405 static int q2t_pci_map_calc_cnt(struct q2t_prm *prm)
406 {
407         int res = 0;
408
409         BUG_ON(prm->sg_cnt == 0);
410
411         /* 32 bit S/G Data Transfer */
412         prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, prm->sg, prm->sg_cnt,
413                                scst_to_tgt_dma_dir(prm->data_direction));
414         if (unlikely(prm->seg_cnt == 0))
415                 goto out_err;
416         /*
417          * If greater than four sg entries then we need to allocate
418          * the continuation entries
419          */
420         if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) {
421                 prm->req_cnt += (uint16_t)(prm->seg_cnt -
422                                 prm->tgt->datasegs_per_cmd) /
423                                 prm->tgt->datasegs_per_cont;
424                 if (((uint16_t)(prm->seg_cnt - prm->tgt->datasegs_per_cmd)) %
425                                         prm->tgt->datasegs_per_cont) 
426                 {
427                         prm->req_cnt++;
428                 }
429         }
430
431 out:
432         TRACE_DBG("seg_cnt=%d, req_cnt=%d, res=%d", prm->seg_cnt, 
433                 prm->req_cnt, res);
434         return res;
435
436 out_err:
437         PRINT_ERROR("qla2x00tgt(%ld): PCI mapping failed: sg_cnt=%d", 
438                 prm->tgt->ha->instance, prm->sg_cnt);
439         res = -1;
440         goto out;
441 }
442
443 /* ha->hardware_lock supposed to be held on entry */
444 static inline uint32_t q2t_make_handle(scsi_qla_host_t *ha)
445 {
446         uint32_t h;
447
448         h = ha->current_cmd;
449         /* always increment cmd handle */
450         do {
451                 ++h;
452                 if (h > MAX_OUTSTANDING_COMMANDS) {
453                         h = 0;
454                 }
455                 if (h == ha->current_cmd) {
456                         TRACE(TRACE_OUT_OF_MEM, "Ran out of empty cmd slots "
457                                 "in ha %p", ha);
458                         h = Q2T_NULL_HANDLE;
459                         break;
460                 }
461         } while ((h == Q2T_NULL_HANDLE) ||
462                  (h == Q2T_BUSY_HANDLE) ||
463                  (h == Q2T_SKIP_HANDLE) || 
464                  (ha->cmds[h] != NULL));
465
466         if (h != Q2T_NULL_HANDLE)
467                 ha->current_cmd = h;
468
469         return h;
470 }
471
472 /* ha->hardware_lock supposed to be held on entry */
473 /*
474  * NOTE: About CTIO_COMPLETION_HANDLE
475  *  This is checked for in qla2x00_process_response_queue() to see
476  *  if a handle coming back in a multi-complete should come to the tgt driver
477  *  or be handled there by qla2xxx
478  */
479 static void q2t_build_ctio_pkt(struct q2t_prm *prm)
480 {
481         uint16_t timeout;
482         uint32_t h;
483
484         prm->pkt = (ctio_common_entry_t *)tgt_data.req_pkt(prm->tgt->ha);
485
486         if (prm->tgt->tgt_enable_64bit_addr)
487                 prm->pkt->entry_type = CTIO_A64_TYPE;
488         else
489                 prm->pkt->entry_type = CONTINUE_TGT_IO_TYPE;
490
491         prm->pkt->entry_count = (uint8_t) prm->req_cnt;
492         
493         h = q2t_make_handle(prm->tgt->ha);
494         if (h != Q2T_NULL_HANDLE) {
495                 prm->tgt->ha->cmds[h] = prm->cmd;
496         }
497         prm->pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
498
499         timeout = Q2T_TIMEOUT;
500         prm->pkt->timeout = cpu_to_le16(timeout);
501
502         /* Set initiator ID */
503         h = GET_TARGET_ID(prm->tgt->ha, &prm->cmd->atio);
504         SET_TARGET_ID(prm->tgt->ha, prm->pkt->target, h);
505                       
506         prm->pkt->exchange_id = prm->cmd->atio.exchange_id;
507
508         TRACE(TRACE_DEBUG|TRACE_SCSI, 
509               "handle(scst_cmd) -> %08x, timeout %d L %#x -> I %#x E %#x",
510               prm->pkt->handle, timeout, le16_to_cpu(prm->cmd->atio.lun),
511               GET_TARGET_ID(prm->tgt->ha, prm->pkt),
512               le16_to_cpu(prm->pkt->exchange_id));
513
514 }
515
516 static void q2t_load_data_segments(struct q2t_prm *prm)
517 {
518         uint32_t cnt;
519         uint32_t *dword_ptr;
520         int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
521
522         TRACE_DBG("iocb->scsi_status=%x, iocb->flags=%x",
523               le16_to_cpu(prm->pkt->scsi_status), le16_to_cpu(prm->pkt->flags));
524
525         prm->pkt->transfer_length = cpu_to_le32(prm->bufflen);
526
527         /* Setup packet address segment pointer */
528         dword_ptr = prm->pkt->dseg_0_address;
529
530         if (prm->seg_cnt == 0) {
531                 /* No data transfer */
532                 *dword_ptr++ = 0;
533                 *dword_ptr = 0;
534
535                 TRACE_BUFFER("No data, CTIO packet data",
536                              prm->pkt, REQUEST_ENTRY_SIZE);
537                 goto out;
538         }
539
540         /* Set total data segment count */
541         prm->pkt->dseg_count = cpu_to_le16(prm->seg_cnt);
542
543         /* If scatter gather */
544         TRACE(TRACE_SG, "%s", "Building S/G data segments...");
545         /* Load command entry data segments */
546         for (cnt = 0;
547              (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt;
548              cnt++, prm->seg_cnt--) 
549         {
550                 *dword_ptr++ =
551                     cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
552                 if (enable_64bit_addressing) {
553                         *dword_ptr++ =
554                             cpu_to_le32(pci_dma_hi32
555                                         (sg_dma_address(prm->sg)));
556                 }
557                 *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
558
559                 TRACE(TRACE_SG, "S/G Segment phys_addr=%llx:%llx, len=%d",
560                       (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
561                       (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
562                       (int)sg_dma_len(prm->sg));
563
564                 prm->sg++;
565         }
566
567         TRACE_BUFFER("Scatter/gather, CTIO packet data",
568                      prm->pkt, REQUEST_ENTRY_SIZE);
569
570         /* Build continuation packets */
571         while (prm->seg_cnt > 0) {
572                 cont_a64_entry_t *cont_pkt64 = 
573                         (cont_a64_entry_t *)tgt_data.req_cont_pkt(prm->tgt->ha);
574
575                 /* 
576                  * Make sure that from cont_pkt64 none of
577                  * 64-bit specific fields used for 32-bit
578                  * addressing. Cast to (cont_entry_t*) for
579                  * that.
580                  */
581
582                 memset(cont_pkt64, 0, sizeof(*cont_pkt64));
583
584                 cont_pkt64->entry_count = 1;
585                 cont_pkt64->sys_define = 0;
586
587                 if (enable_64bit_addressing) {
588                         cont_pkt64->entry_type = CONTINUE_A64_TYPE;
589                         dword_ptr =
590                             (uint32_t*)&cont_pkt64->dseg_0_address;
591                 } else {
592                         cont_pkt64->entry_type = CONTINUE_TYPE;
593                         dword_ptr =
594                             (uint32_t*)&((cont_entry_t *)
595                                             cont_pkt64)->dseg_0_address;
596                 }
597
598                 /* Load continuation entry data segments */
599                 for (cnt = 0;
600                      cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt;
601                      cnt++, prm->seg_cnt--) 
602                 {
603                         *dword_ptr++ =
604                             cpu_to_le32(pci_dma_lo32
605                                         (sg_dma_address(prm->sg)));
606                         if (enable_64bit_addressing) {
607                                 *dword_ptr++ =
608                                     cpu_to_le32(pci_dma_hi32
609                                                 (sg_dma_address
610                                                  (prm->sg)));
611                         }
612                         *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
613
614                         TRACE(TRACE_SG,
615                               "S/G Segment Cont. phys_addr=%llx:%llx, "
616                               "len=%d",
617                               (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
618                               (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
619                               (int)sg_dma_len(prm->sg));
620
621                         prm->sg++;
622                 }
623
624                 TRACE_BUFFER("Continuation packet data",
625                              cont_pkt64, REQUEST_ENTRY_SIZE);
626         }
627
628 out:
629         return;
630 }
631
632 static void q2t_init_ctio_ret_entry(ctio_ret_entry_t *ctio_m1,
633         struct q2t_prm *prm)
634 {
635         TRACE_ENTRY();
636
637         prm->sense_buffer_len = min((uint32_t)prm->sense_buffer_len, 
638                                     (uint32_t)sizeof(ctio_m1->sense_data));
639
640         ctio_m1->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
641                                                 OF_NO_DATA | OF_SS_MODE_1);
642         ctio_m1->flags |= __constant_cpu_to_le16(OF_INC_RC);
643         ctio_m1->scsi_status = cpu_to_le16(prm->rq_result);
644         ctio_m1->residual = cpu_to_le32(prm->residual);
645         if (SCST_SENSE_VALID(prm->sense_buffer)) {
646                 ctio_m1->scsi_status |=
647                                 __constant_cpu_to_le16(SS_SENSE_LEN_VALID);
648                 ctio_m1->sense_length = cpu_to_le16(prm->sense_buffer_len);
649                 memcpy(ctio_m1->sense_data, prm->sense_buffer,
650                        prm->sense_buffer_len);
651         } else {
652                 memset(ctio_m1->sense_data, 0, sizeof(ctio_m1->sense_data));
653                 ctio_m1->sense_length = 0;
654         }
655
656         TRACE_BUFFER("CTIO returned packet data", ctio_m1, REQUEST_ENTRY_SIZE);
657
658         /* Sense with len > 26, is it possible ??? */
659
660         TRACE_EXIT();
661         return;
662 }
663
664 static inline int q2t_has_data(struct scst_cmd *scst_cmd)
665 {
666         return scst_cmd_get_resp_data_len(scst_cmd) > 0;
667 }
668
669 static int q2t_xmit_response(struct scst_cmd *scst_cmd)
670 {
671         int res = SCST_TGT_RES_SUCCESS;
672         struct q2t_sess *sess;
673         int resp_flags;
674         unsigned long flags = 0;
675         struct q2t_prm prm = { 0 };
676         int data_sense_flag = 0;
677         uint16_t full_req_cnt;
678
679         TRACE_ENTRY();
680         TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd));
681
682         prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
683         sess = (struct q2t_sess *)
684                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
685
686         if (unlikely(scst_cmd_aborted(scst_cmd))) {
687                 scsi_qla_host_t *ha = sess->tgt->ha;
688
689                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): terminating exchange "
690                         "for aborted scst_cmd=%p (tag=%d)",
691                         ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd));
692
693                 prm.cmd->state = Q2T_STATE_ABORTED;
694
695                 q2t_send_term_exchange(ha, prm.cmd, &prm.cmd->atio, 0);
696                 /* !! At this point cmd could be already freed !! */
697                 goto out;
698         }
699
700         prm.sg = scst_cmd_get_sg(scst_cmd);
701         prm.bufflen = scst_cmd_get_resp_data_len(scst_cmd);
702         prm.sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
703         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
704         prm.rq_result = scst_cmd_get_status(scst_cmd);
705         prm.sense_buffer = scst_cmd_get_sense_buffer(scst_cmd);
706         prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
707         prm.tgt = sess->tgt;
708         prm.seg_cnt = 0;
709         prm.req_cnt = 1;
710         resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
711
712         TRACE_DBG("rq_result=%x, resp_flags=%x", prm.rq_result, resp_flags);
713         if (prm.rq_result != 0)
714                 TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
715
716         if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) {
717                 /* ToDo, after it's done in SCST */
718                 PRINT_ERROR("qla2x00tgt(%ld): SCST_TSC_FLAG_STATUS not set: "
719                      "feature not implemented", prm.tgt->ha->instance);
720                 res = SCST_TGT_RES_FATAL_ERROR;
721                 goto out;
722         }
723
724         /* Acquire ring specific lock */
725         spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
726
727         /* Send marker if required */
728         if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
729                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
730                             "failed", prm.tgt->ha->instance);
731                 res = SCST_TGT_RES_FATAL_ERROR;
732                 goto out_unlock;
733         }
734
735         TRACE_DBG("CTIO start: ha(%d)", (int) prm.tgt->ha->instance);
736
737         if (q2t_has_data(scst_cmd)) {
738                 if (q2t_pci_map_calc_cnt(&prm) != 0) {
739                         res = SCST_TGT_RES_QUEUE_FULL;
740                         goto out_unlock;
741                 }
742                 full_req_cnt = prm.req_cnt;
743                 if (SCST_SENSE_VALID(prm.sense_buffer)) {
744                         data_sense_flag = 1;
745                         full_req_cnt++;
746                 }
747         } else
748                 full_req_cnt = prm.req_cnt;
749
750         q2t_build_ctio_pkt(&prm);
751
752         if (prm.data_direction != SCST_DATA_WRITE) {
753                 prm.residual =
754                     le32_to_cpu(prm.cmd->atio.data_length) - prm.bufflen;
755                 if (prm.residual > 0) {
756                         TRACE_DBG("Residual underflow: %d", prm.residual);
757                         prm.rq_result |= SS_RESIDUAL_UNDER;
758                 } else if (prm.residual < 0) {
759                         TRACE_DBG("Residual overflow: %d", prm.residual);
760                         prm.rq_result |= SS_RESIDUAL_OVER;
761                         prm.residual = -prm.residual;
762                 }
763
764                 if (q2t_has_data(scst_cmd)) {
765                         prm.pkt->flags |= __constant_cpu_to_le16(
766                                 OF_FAST_POST | OF_INC_RC | OF_DATA_IN);
767
768                         q2t_load_data_segments(&prm);
769
770                         if (data_sense_flag == 0) {
771                                 prm.pkt->scsi_status = cpu_to_le16(
772                                         prm.rq_result);
773                                 prm.pkt->residual = cpu_to_le32(prm.residual);
774                                 prm.pkt->flags |= 
775                                         __constant_cpu_to_le16(OF_SSTS);
776                         } else {
777                                 ctio_ret_entry_t *ctio_m1 = 
778                                         (ctio_ret_entry_t *)
779                                         tgt_data.req_cont_pkt(prm.tgt->ha);
780
781                                 TRACE_DBG("%s", "Building additional status "
782                                         "packet");
783
784                                 memcpy(ctio_m1, prm.pkt, sizeof(*ctio_m1));
785                                 ctio_m1->entry_count = 1;
786
787                                 /* Real finish is ctio_m1's finish */
788                                 prm.pkt->handle = Q2T_SKIP_HANDLE |
789                                                 CTIO_COMPLETION_HANDLE_MARK;
790
791                                 prm.pkt->flags &= ~__constant_cpu_to_le16(OF_INC_RC);
792
793                                 q2t_init_ctio_ret_entry(ctio_m1, &prm);
794                                 TRACE_BUFFER("Status CTIO packet data", ctio_m1,
795                                         REQUEST_ENTRY_SIZE);
796                         }
797                 } else
798                         q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
799         } else {
800                 q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
801         }
802         
803         prm.cmd->state = Q2T_STATE_PROCESSED;   /* Mid-level is done processing */
804
805         TRACE_BUFFER("Xmitting", prm.pkt, REQUEST_ENTRY_SIZE);
806
807         q2t_exec_queue(prm.tgt->ha);
808
809 out_unlock:
810         /* Release ring specific lock */
811         spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
812
813 out:
814         TRACE_EXIT_RES(res);
815         return res;
816 }
817
818 static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
819 {
820         int res = SCST_TGT_RES_SUCCESS;
821         struct q2t_sess *sess;
822         unsigned long flags = 0;
823         struct q2t_prm prm = { 0 };
824
825         TRACE_ENTRY();
826         TRACE(TRACE_SCSI, "tag=%d", scst_cmd_get_tag(scst_cmd));
827
828         prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
829         sess = (struct q2t_sess *)
830                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
831
832         prm.sg = scst_cmd_get_sg(scst_cmd);
833         prm.bufflen = scst_cmd_get_bufflen(scst_cmd);
834         prm.sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
835         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
836         prm.tgt = sess->tgt;
837         prm.req_cnt = 1;
838
839         /* Acquire ring specific lock */
840         spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
841
842         /* Send marker if required */
843         if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
844                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
845                             "failed", prm.tgt->ha->instance);
846                 res = SCST_TGT_RES_FATAL_ERROR;
847                 goto out_unlock;
848         }
849
850         TRACE_DBG("CTIO_start: ha(%d)", (int) prm.tgt->ha->instance);
851
852         /* Calculate number of entries and segments required */
853         if (q2t_pci_map_calc_cnt(&prm) != 0) {
854                 res = SCST_TGT_RES_QUEUE_FULL;
855                 goto out_unlock;
856         }
857
858         prm.cmd->iocb_cnt = prm.req_cnt;
859
860         q2t_build_ctio_pkt(&prm);
861
862         prm.pkt->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_DATA_OUT);
863
864         q2t_load_data_segments(&prm);
865
866         prm.cmd->state = Q2T_STATE_NEED_DATA;
867
868         TRACE_BUFFER("Xfering", prm.pkt, REQUEST_ENTRY_SIZE);
869
870         q2t_exec_queue(prm.tgt->ha);
871         
872 out_unlock:
873         /* Release ring specific lock */
874         spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
875
876         TRACE_EXIT_RES(res);
877         return res;
878 }
879
880 static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
881         atio_entry_t *atio, int ha_locked)
882 {
883         ctio_ret_entry_t *ctio;
884         unsigned long flags = 0;
885         int do_tgt_cmd_done = 0;
886
887         TRACE_ENTRY();
888
889         TRACE_DBG("Sending TERM EXCH CTIO (ha=%p)", ha);
890
891         if (!ha_locked)
892                 spin_lock_irqsave(&ha->hardware_lock, flags);
893
894         /* Send marker if required */
895         if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
896                 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
897                             "failed", ha->instance);
898                 goto out_unlock;
899         }
900
901         ctio = (ctio_ret_entry_t*)tgt_data.req_pkt(ha);
902         if (ctio == NULL) {
903                 PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
904                         "request packet", ha->instance, __func__);
905                 goto out_unlock;
906         }
907
908         ctio->entry_type = CTIO_RET_TYPE;
909         ctio->entry_count = 1;
910
911         if (cmd != NULL) {
912                 ctio->handle = q2t_make_handle(ha);
913                 if (ctio->handle != Q2T_NULL_HANDLE) {
914                         ha->cmds[ctio->handle] = cmd;
915                 } else {
916                         ctio->handle = Q2T_SKIP_HANDLE;
917                         do_tgt_cmd_done = 1;
918                 }
919         } else
920                 ctio->handle = Q2T_SKIP_HANDLE;
921
922         ctio->handle |= CTIO_COMPLETION_HANDLE_MARK;
923
924         SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
925         ctio->exchange_id = atio->exchange_id;
926
927         ctio->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_TERM_EXCH |
928                         OF_NO_DATA | OF_SS_MODE_1);
929         ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
930
931         TRACE_BUFFER("CTIO TERM EXCH packet data", ctio, REQUEST_ENTRY_SIZE);
932
933         q2t_exec_queue(ha);
934
935 out_unlock:
936         if (!ha_locked)
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 static 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 | CTIO_COMPLETION_HANDLE_MARK;
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_find_name(scsi_qla_host_t *ha, int loop_id)
1265 {
1266         int wwn_found = 0;
1267         char *wwn_str;
1268         fc_port_t *fcl;
1269
1270         wwn_str = kmalloc(2*WWN_SIZE, GFP_ATOMIC);
1271         if (wwn_str == NULL) {
1272                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1273                 goto out;
1274         }
1275
1276         /* Find the WWN in the port db given the loop_id */
1277         list_for_each_entry(fcl, &ha->fcports, list) {
1278             if (loop_id == (fcl->loop_id & 0xFF)) {
1279                 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1280                         fcl->port_name[0], fcl->port_name[1], 
1281                         fcl->port_name[2], fcl->port_name[3], 
1282                         fcl->port_name[4], fcl->port_name[5], 
1283                         fcl->port_name[6], fcl->port_name[7]);
1284                 TRACE_DBG("found wwn: %s for loop_id: %d", wwn_str, loop_id);
1285                 wwn_found = 1;
1286                 break;
1287             }
1288         }
1289
1290         if (wwn_found == 0) {
1291                 TRACE_MGMT_DBG("qla2x00tgt(%ld): Unable to find wwn login for "
1292                         "loop id %d", ha->instance, loop_id);
1293                 kfree(wwn_str);
1294                 wwn_str = NULL;
1295         }
1296
1297 out:
1298         return wwn_str;
1299 }
1300
1301 static char *q2t_make_name(scsi_qla_host_t *ha, const uint8_t *name)
1302 {
1303         char *wwn_str;
1304
1305         wwn_str = kmalloc(3*WWN_SIZE, GFP_ATOMIC);
1306         if (wwn_str == NULL) {
1307                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1308                 goto out;
1309         }
1310         sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1311                 name[1], name[0], name[3], name[2], name[5], name[4], 
1312                 name[7], name[6]);
1313
1314 out:
1315         return wwn_str;
1316 }
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;
1380                         if (IS_QLA2200(ha))
1381                                 name = q2t_find_name(ha, loop_id);
1382                         else {
1383                                 name = q2t_make_name(ha,
1384                                         atio->initiator_port_name);
1385                         }
1386                         if (name == NULL) {
1387                                 res = -ESRCH;
1388                                 goto out_free_sess;
1389                         }
1390
1391                         sess->scst_sess = scst_register_session(
1392                                 tgt->scst_tgt, 1, name, sess,
1393                                 q2t_alloc_session_done);
1394                         kfree(name);
1395                 }
1396
1397                 if (sess->scst_sess == NULL) {
1398                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() failed "
1399                              "for host %ld(%p)", ha->instance, ha->host_no, ha);
1400                         res = -EFAULT;
1401                         goto out_free_sess;
1402                 }
1403                 scst_sess_set_tgt_priv(sess->scst_sess, sess);
1404
1405                 /* add session data to host data structure */
1406                 list_add(&sess->list, &tgt->sess_list);
1407                 atomic_inc(&tgt->sess_count);
1408         }
1409
1410         cmd->sess = sess;
1411         res = q2t_do_send_cmd_to_scst(ha, cmd);
1412         if (res != 0)
1413                 goto out_free_cmd;
1414
1415 out:
1416         TRACE_EXIT_RES(res);
1417         return res;
1418
1419 out_free_sess:
1420         kfree(sess);
1421         smp_mb__before_atomic_dec();
1422         if (atomic_dec_and_test(&tgt->sess_count))
1423                 wake_up_all(&tgt->waitQ);
1424         /* go through */
1425
1426 out_free_cmd:
1427         q2t_free_cmd(cmd);
1428         goto out;
1429 }
1430
1431 /* ha->hardware_lock supposed to be held on entry */
1432 static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
1433 {
1434         int res = 0, rc = -1;
1435         struct q2t_mgmt_cmd *mcmd;
1436         struct q2t_tgt *tgt;
1437         struct q2t_sess *sess;
1438         int loop_id;
1439         uint16_t lun;
1440
1441         TRACE_ENTRY();
1442
1443         tgt = ha->tgt;
1444         loop_id = GET_TARGET_ID(ha, iocb);
1445
1446         /* Make it be in network byte order */
1447         lun = swab16(iocb->lun);
1448
1449         sess = q2t_find_sess_by_lid(tgt, loop_id);
1450         if (sess == NULL) {
1451                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task mgmt fn 0x%x for "
1452                       "non-existant session", ha->instance, iocb->task_flags);
1453                 res = -EFAULT;
1454                 goto out;
1455         }
1456
1457         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1458         if (mcmd == NULL) {
1459                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1460                 res = -ENOMEM;
1461                 goto out;
1462         }
1463
1464         mcmd->sess = sess;
1465         mcmd->notify_entry = *iocb;
1466
1467         switch (iocb->task_flags) {
1468         case IMM_NTFY_CLEAR_ACA:
1469                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1470                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1471                                          (uint8_t *)&lun, sizeof(lun), 
1472                                          SCST_ATOMIC, mcmd);
1473                 break;
1474
1475         case IMM_NTFY_TARGET_RESET:
1476                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1477                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1478                                          (uint8_t *)&lun, sizeof(lun), 
1479                                          SCST_ATOMIC, mcmd);
1480                 break;
1481
1482         case IMM_NTFY_LUN_RESET:
1483                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1484                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1485                                          (uint8_t *)&lun, sizeof(lun), 
1486                                          SCST_ATOMIC, mcmd);
1487                 break;
1488
1489         case IMM_NTFY_CLEAR_TS:
1490                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1491                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1492                                          (uint8_t *)&lun, sizeof(lun), 
1493                                          SCST_ATOMIC, mcmd);
1494                 break;
1495
1496         case IMM_NTFY_ABORT_TS:
1497                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1498                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1499                                          (uint8_t *)&lun, sizeof(lun), 
1500                                          SCST_ATOMIC, mcmd);
1501                 break;
1502
1503         default:
1504                 PRINT_ERROR("qla2x00tgt(%ld): Unknown task mgmt fn 0x%x",
1505                             ha->instance, iocb->task_flags);
1506                 break;
1507         }
1508
1509         if (rc != 0) {
1510                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_lun() failed: %d",
1511                             ha->instance, rc);
1512                 res = -EFAULT;
1513                 goto out_free;
1514         }
1515
1516 out:
1517         TRACE_EXIT_RES(res);
1518         return res;
1519
1520 out_free:
1521         kfree(mcmd);
1522         goto out;
1523 }
1524
1525 /* ha->hardware_lock supposed to be held on entry */
1526 static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
1527 {
1528         int res = 0, rc;
1529         struct q2t_mgmt_cmd *mcmd;
1530         struct q2t_sess *sess;
1531         int loop_id;
1532         uint32_t tag;
1533
1534         TRACE_ENTRY();
1535
1536         loop_id = GET_TARGET_ID(ha, iocb);
1537         tag = le16_to_cpu(iocb->seq_id);
1538
1539         sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1540         if (sess == NULL) {
1541                 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task abort for unexisting "
1542                         "session", ha->instance);
1543                 res = -EFAULT;
1544                 goto out;
1545         }
1546         
1547         mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1548         if (mcmd == NULL) {
1549                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1550                 res = -ENOMEM;
1551                 goto out;
1552         }
1553
1554         mcmd->sess = sess;
1555         mcmd->notify_entry = *iocb;
1556
1557         rc = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, tag, 
1558                 SCST_ATOMIC, mcmd);
1559         if (rc != 0) {
1560                 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_tag() failed: %d",
1561                             ha->instance, rc);
1562                 res = -EFAULT;
1563                 goto out_free;
1564         }
1565
1566 out:
1567         TRACE_EXIT_RES(res);
1568         return res;
1569
1570 out_free:
1571         kfree(mcmd);
1572         goto out;
1573 }
1574
1575 /* SCST Callback */
1576 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
1577 {
1578         struct q2t_mgmt_cmd *mcmd;
1579         unsigned long flags;
1580
1581         TRACE_ENTRY();
1582
1583         TRACE(TRACE_MGMT, "scst_mcmd (%p) status %#x state %#x", scst_mcmd, 
1584               scst_mcmd->status, scst_mcmd->state);
1585
1586         mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd);
1587         if (unlikely(mcmd == NULL)) {
1588                 PRINT_ERROR("scst_mcmd %p tgt_spec is NULL", mcmd);
1589                 goto out;
1590         }
1591
1592         spin_lock_irqsave(&mcmd->sess->tgt->ha->hardware_lock, flags);
1593         q2t_send_notify_ack(mcmd->sess->tgt->ha, &mcmd->notify_entry, 0,
1594                 (scst_mgmt_cmd_get_status(scst_mcmd) == SCST_MGMT_STATUS_SUCCESS)
1595                          ? 0 : FC_TM_FAILED, 1);
1596         spin_unlock_irqrestore(&mcmd->sess->tgt->ha->hardware_lock, flags);
1597
1598         /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */
1599         scst_mcmd->tgt_priv = NULL;
1600         kfree(mcmd);
1601
1602 out:
1603         TRACE_EXIT();
1604         return;
1605 }
1606
1607 /* ha->hardware_lock supposed to be held on entry */
1608 static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
1609 {
1610         uint16_t status;
1611         int loop_id;
1612         uint32_t add_flags = 0;
1613         int send_notify_ack = 1;
1614
1615         TRACE_ENTRY();
1616
1617         status = le16_to_cpu(iocb->status);
1618         loop_id = GET_TARGET_ID(ha, iocb);
1619
1620         if (!ha->flags.enable_target_mode || ha->tgt == NULL) {
1621                 TRACE(TRACE_MGMT_DEBUG|TRACE_SCSI|TRACE_DEBUG,
1622                       "Acking %04x S %04x I %#x -> L %#x", status, 
1623                       le16_to_cpu(iocb->seq_id), loop_id,
1624                       le16_to_cpu(iocb->lun));
1625                 goto out;
1626         }
1627
1628         TRACE_BUFFER("IMMED Notify Coming Up", iocb, sizeof(*iocb));
1629         
1630         switch (status) {
1631         case IMM_NTFY_LIP_RESET:
1632                 TRACE(TRACE_MGMT, "LIP reset (I %#x)", loop_id);
1633                 /* 
1634                  * ToDo: doing so we reset all holding RESERVE'ations, 
1635                  * which could be unexpected, so be more carefull here 
1636                  */
1637                 q2t_clear_tgt_db(ha->tgt);
1638                 /* set the Clear LIP reset event flag */
1639                 add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET;
1640                 break;
1641
1642         case IMM_NTFY_IOCB_OVERFLOW:
1643                 PRINT_ERROR("qla2x00tgt(%ld): Cannot provide requested "
1644                         "capability (IOCB overflow)", ha->instance);
1645                 break;
1646
1647         case IMM_NTFY_ABORT_TASK:
1648                 TRACE(TRACE_MGMT, "Abort Task (S %04x I %#x -> L %#x)", 
1649                       le16_to_cpu(iocb->seq_id), loop_id,
1650                       le16_to_cpu(iocb->lun));
1651                 if (q2t_abort_task(ha, iocb) == 0)
1652                         send_notify_ack = 0;
1653                 break;
1654
1655         case IMM_NTFY_PORT_LOGOUT:
1656                 TRACE(TRACE_MGMT, "Port logout (S %04x I %#x -> L %#x)", 
1657                       le16_to_cpu(iocb->seq_id), loop_id,
1658                       le16_to_cpu(iocb->lun));
1659                 /* 
1660                  * ToDo: doing so we reset all holding RESERVE'ations, 
1661                  * which could be unexpected, so be more carefull here 
1662                  */
1663                 q2t_port_logout(ha, loop_id);
1664                 break;
1665
1666         case IMM_NTFY_PORT_CONFIG:
1667         case IMM_NTFY_GLBL_TPRLO:
1668         case IMM_NTFY_GLBL_LOGO:
1669                 /* ToDo: ports DB changes handling ?? */
1670                 TRACE(TRACE_MGMT, "Port config changed, Global TPRLO or "
1671                       "Global LOGO (%d)", status);
1672                 /* 
1673                  * ToDo: doing so we reset all holding RESERVE'ations, 
1674                  * which could be unexpected, so be more carefull here 
1675                  */
1676                 q2t_clear_tgt_db(ha->tgt);
1677                 break;
1678
1679         case IMM_NTFY_RESOURCE:
1680                 PRINT_ERROR("qla2x00tgt(%ld): Out of resources, host %ld",
1681                             ha->instance, ha->host_no);
1682                 break;
1683
1684         case IMM_NTFY_MSG_RX:
1685                 TRACE(TRACE_MGMT, "Immediate notify task %x", iocb->task_flags);
1686                 if (q2t_handle_task_mgmt(ha, iocb) == 0)
1687                         send_notify_ack = 0;
1688                 break;
1689
1690         default:
1691                 PRINT_ERROR("qla2x00tgt(%ld): Received unknown immediate "
1692                         "notify status %x", ha->instance, status);
1693                 break;
1694         }
1695
1696
1697 out:
1698         if (send_notify_ack)
1699                 q2t_send_notify_ack(ha, iocb, add_flags, 0, 0);
1700
1701         TRACE_EXIT();
1702         return;
1703 }
1704
1705 /* ha->hardware_lock supposed to be held on entry */
1706 /* called via callback from qla2xxx */
1707 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
1708 {
1709         atio_entry_t *atio;
1710
1711         TRACE_ENTRY();
1712         
1713         BUG_ON((ha == NULL) || (pkt == NULL));
1714
1715         TRACE(TRACE_SCSI, "pkt %p: T %02x C %02x S %02x handle %#x",
1716               pkt, pkt->entry_type, pkt->entry_count, pkt->entry_status,
1717               pkt->handle);
1718
1719         if (pkt->entry_status != 0) {
1720                 PRINT_ERROR("qla2x00tgt(%ld): Received response packet %x "
1721                      "with error status %x", ha->instance, pkt->entry_type,
1722                      pkt->entry_status);
1723                 goto out;
1724         }
1725
1726         switch (pkt->entry_type) {
1727         case ACCEPT_TGT_IO_TYPE:
1728                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1729                         int rc;
1730                         atio = (atio_entry_t *)pkt;
1731                         TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x "
1732                                   "lun %04x read/write %d data_length %08x "
1733                                   "target_id %02x exchange_id %04x ", 
1734                                   ha->instance, le16_to_cpu(atio->status),
1735                                   le16_to_cpu(atio->lun), 
1736                                   atio->execution_codes,
1737                                   le32_to_cpu(atio->data_length),
1738                                   GET_TARGET_ID(ha, atio),
1739                                   le16_to_cpu(atio->exchange_id));
1740                         if (atio->status !=
1741                                 __constant_cpu_to_le16(ATIO_CDB_VALID)) {
1742                                 PRINT_ERROR("qla2x00tgt(%ld): ATIO with error "
1743                                             "status %x received", ha->instance, 
1744                                             le16_to_cpu(atio->status));
1745                                 break;
1746                         }
1747                         TRACE_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb,
1748                                         sizeof(atio->cdb));
1749                         rc = q2t_send_cmd_to_scst(ha, atio);
1750                         if (unlikely(rc != 0)) {
1751                                 if (rc == -ESRCH) {
1752 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
1753                                         q2t_send_busy(ha, atio);
1754 #else
1755                                         q2t_send_term_exchange(ha, NULL, atio, 1);
1756 #endif
1757                                 } else {
1758                                         PRINT_INFO("qla2x00tgt(%ld): Unable to "
1759                                             "send the command to SCSI target "
1760                                             "mid-level, sending BUSY status", 
1761                                             ha->instance);
1762                                         q2t_send_busy(ha, atio);
1763                                 }
1764                         }
1765                 } else {
1766                         PRINT_ERROR("qla2x00tgt(%ld): ATIO, but target mode "
1767                                 "disabled", ha->instance);
1768                 }
1769                 break;
1770                         
1771         case CONTINUE_TGT_IO_TYPE:
1772                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1773                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1774                         TRACE_DBG("CONTINUE_TGT_IO: instance %ld",
1775                                   ha->instance);
1776                         q2t_do_ctio_completion(ha, entry->handle,
1777                                                le16_to_cpu(entry->status), 
1778                                                entry);
1779                 } else {
1780                         PRINT_ERROR("qla2x00tgt(%ld): CTIO, but target mode "
1781                                 "disabled", ha->instance);
1782                 }
1783                 break;
1784                 
1785         case CTIO_A64_TYPE:
1786                 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1787                         ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1788                         TRACE_DBG("CTIO_A64: instance %ld", ha->instance);
1789                         q2t_do_ctio_completion(ha, entry->handle, 
1790                                                le16_to_cpu(entry->status), 
1791                                                entry);
1792                 } else {
1793                         PRINT_ERROR("qla2x00tgt(%ld): CTIO_A64, but target "
1794                                 "mode disabled", ha->instance);
1795                 }
1796                 break;
1797                         
1798         case IMMED_NOTIFY_TYPE:
1799                 TRACE_DBG("%s", "IMMED_NOTIFY");
1800                 q2t_handle_imm_notify(ha, (notify_entry_t *)pkt);
1801                 break;
1802
1803         case NOTIFY_ACK_TYPE:
1804                 if (ha->tgt == NULL) {
1805                         PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK recieved "
1806                                 "with NULL tgt", ha->instance);
1807                 } else if (ha->tgt->notify_ack_expected > 0) {
1808                         nack_entry_t *entry = (nack_entry_t *)pkt;
1809                         TRACE_DBG("NOTIFY_ACK seq %04x status %x", 
1810                                   le16_to_cpu(entry->seq_id),
1811                                   le16_to_cpu(entry->status));
1812                         ha->tgt->notify_ack_expected--;
1813                         if (entry->status !=
1814                                 __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) {
1815                                 PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK "
1816                                             "failed %x", ha->instance, 
1817                                             le16_to_cpu(entry->status));
1818                         }
1819                 } else {
1820                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected NOTIFY_ACK "
1821                                     "received", ha->instance);
1822                 }
1823                 break;
1824
1825         case MODIFY_LUN_TYPE: 
1826                 if ((ha->tgt != NULL) && (ha->tgt->modify_lun_expected > 0)) {
1827                         struct q2t_tgt *tgt = ha->tgt;
1828                         modify_lun_entry_t *entry = (modify_lun_entry_t *)pkt;
1829                         TRACE_DBG("MODIFY_LUN %x, imm %c%d, cmd %c%d", 
1830                                   entry->status,
1831                                   (entry->operators & MODIFY_LUN_IMM_ADD) ?'+' 
1832                                   :(entry->operators & MODIFY_LUN_IMM_SUB) ?'-' 
1833                                   :' ', 
1834                                   entry->immed_notify_count, 
1835                                   (entry->operators & MODIFY_LUN_CMD_ADD) ?'+' 
1836                                   :(entry->operators & MODIFY_LUN_CMD_SUB) ?'-'
1837                                   :' ', 
1838                                   entry->command_count);
1839                         tgt->modify_lun_expected--;
1840                         if (entry->status != MODIFY_LUN_SUCCESS) {
1841                                 PRINT_ERROR("qla2x00tgt(%ld): MODIFY_LUN "
1842                                             "failed %x", ha->instance, 
1843                                             entry->status);
1844                         }
1845                         tgt->disable_lun_status = entry->status;
1846                         wake_up_all(&tgt->waitQ);
1847
1848                 } else {
1849                         PRINT_ERROR("qla2x00tgt(%ld): Unexpected MODIFY_LUN "
1850                                     "received", (ha != NULL) ?ha->instance :-1);
1851                 }
1852                 break;
1853
1854         case ENABLE_LUN_TYPE:
1855                 if (ha->tgt != NULL) {
1856                         struct q2t_tgt *tgt = ha->tgt;
1857                         elun_entry_t *entry = (elun_entry_t *)pkt;
1858                         TRACE_DBG("ENABLE_LUN %x imm %u cmd %u ", 
1859                                   entry->status, entry->immed_notify_count,
1860                                   entry->command_count);
1861                         if ((ha->flags.enable_target_mode) &&
1862                             (entry->status == ENABLE_LUN_ALREADY_ENABLED)) {
1863                                 TRACE_DBG("LUN is already enabled: %#x",
1864                                           entry->status);
1865                                 entry->status = ENABLE_LUN_SUCCESS;
1866                         } else if (entry->status == ENABLE_LUN_RC_NONZERO) {
1867                                 TRACE_DBG("ENABLE_LUN succeeded but with error: "
1868                                           "%#x", entry->status);
1869                                 entry->status = ENABLE_LUN_SUCCESS;
1870                         } else if (entry->status != ENABLE_LUN_SUCCESS) {
1871                                 PRINT_ERROR("qla2x00tgt(%ld): ENABLE_LUN " 
1872                                             "failed %x", 
1873                                             ha->instance, entry->status);
1874                                 ha->flags.enable_target_mode =
1875                                         ~ha->flags.enable_target_mode;
1876                         } /* else success */
1877                         tgt->disable_lun_status = entry->status;
1878                         wake_up_all(&tgt->waitQ);
1879                 }
1880                 break;
1881
1882         default:
1883                 PRINT_INFO("qla2x00tgt(%ld): Received unknown response pkt "
1884                      "type %x", ha->instance, pkt->entry_type);
1885                 break;
1886         }
1887
1888 out:
1889         TRACE_EXIT();
1890         return;
1891 }
1892
1893 /* ha->hardware_lock supposed to be held on entry */
1894 /* called via callback from qla2xxx */
1895 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha, uint16_t *mailbox)
1896 {
1897         TRACE_ENTRY();
1898
1899         BUG_ON(ha == NULL);
1900
1901         if (ha->tgt == NULL) {
1902                 TRACE(TRACE_DEBUG|TRACE_MGMT, 
1903                       "ASYNC EVENT %#x but no tgt. ha %p tgt_flag %d",
1904                       code, ha, ha->flags.enable_target_mode);
1905                 goto out;
1906         }
1907
1908         switch (code) {
1909         case MBA_RESET:                 /* Reset */
1910         case MBA_SYSTEM_ERR:            /* System Error */
1911         case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
1912         case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
1913         case MBA_LOOP_DOWN:
1914         case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
1915         case MBA_LIP_RESET:             /* LIP reset occurred */
1916         case MBA_POINT_TO_POINT:        /* Point to point mode. */
1917         case MBA_CHG_IN_CONNECTION:     /* Change in connection mode. */
1918                 TRACE_MGMT_DBG("Async event %#x occured: clear tgt_db", code);
1919 #if 0
1920                 /* 
1921                  * ToDo: doing so we reset all holding RESERVE'ations, 
1922                  * which could be unexpected, so be more carefull here 
1923                  */
1924                 q2t_clear_tgt_db(ha->tgt);
1925 #endif
1926                 break;
1927         case MBA_RSCN_UPDATE:
1928                 TRACE_MGMT_DBG("RSCN Update (%x) N_Port %#06x (fmt %x)",
1929                       code, ((mailbox[1]&0xF)<<2)|le16_to_cpu(mailbox[2]), 
1930                       (mailbox[1]&0xF0)>>1);
1931                 break;
1932
1933         case MBA_PORT_UPDATE:           /* Port database update occurred */
1934                 TRACE_MGMT_DBG("Port DB Chng: L_ID %#4x did %d: ignore",
1935                       le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]));
1936                 break;
1937
1938         case MBA_LOOP_UP:
1939         default:
1940                 TRACE_MGMT_DBG("Async event %#x occured: ignore", code);
1941                 /* just don't DO anything */
1942                 break;
1943         }
1944
1945 out:
1946         TRACE_EXIT();
1947         return;
1948 }
1949
1950 /* no lock held on entry */
1951 /* called via callback from qla2xxx */
1952 static void q2t_host_action(scsi_qla_host_t *ha, 
1953                             qla2x_tgt_host_action_t action)
1954 {
1955         struct q2t_tgt *tgt = NULL;
1956         unsigned long flags = 0;
1957
1958         TRACE_ENTRY();
1959
1960         BUG_ON(ha == NULL);
1961
1962         switch (action) {
1963         case ENABLE_TARGET_MODE :
1964                 tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
1965                 if (tgt == NULL) {
1966                         TRACE(TRACE_OUT_OF_MEM, "%s",
1967                               "Allocation of tgt failed");
1968                         goto out;
1969                 }
1970                 
1971                 tgt->ha = ha;
1972                 tgt->disable_lun_status = Q2T_DISABLE_LUN_STATUS_NOT_SET;
1973                 INIT_LIST_HEAD(&tgt->sess_list);
1974                 atomic_set(&tgt->sess_count, 0);
1975                 init_waitqueue_head(&tgt->waitQ);
1976                 
1977                 if (ha->flags.enable_64bit_addressing) {
1978                         PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
1979                                    "Addressing Enabled", ha->instance);
1980                         tgt->tgt_enable_64bit_addr = 1;
1981                         /* 3 is reserved */
1982                         tgt_template.sg_tablesize = 
1983                                 QLA_MAX_SG64(ha->request_q_length - 3);
1984                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
1985                         tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
1986                 } else {
1987                         PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
1988                                    "PCI Addressing", ha->instance);
1989                         if (tgt_template.sg_tablesize == 0) {
1990                                 tgt_template.sg_tablesize =
1991                                         QLA_MAX_SG32(ha->request_q_length - 3);
1992                         }
1993                         tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
1994                         tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
1995                 }
1996                 
1997                 tgt->scst_tgt = scst_register(&tgt_template);
1998                 if (!tgt->scst_tgt) {
1999                         PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
2000                                     "failed for host %ld(%p)", ha->instance, 
2001                                     ha->host_no, ha);
2002                         kfree(tgt);
2003                         goto out;
2004                 }
2005                 
2006                 scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
2007                 
2008                 spin_lock_irqsave(&ha->hardware_lock, flags);
2009                 ha->tgt = tgt;
2010                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2011
2012                 TRACE_DBG("Enable lun for host %ld(%ld,%p)",
2013                           ha->host_no, ha->instance, ha);
2014                 tgt_data.enable_lun(ha);
2015                 
2016                 break;
2017         case DISABLE_TARGET_MODE :
2018                 spin_lock_irqsave(&ha->hardware_lock, flags);
2019                 if (ha->tgt == NULL) {
2020                         /* ensure target mode is marked as off */
2021                         ha->flags.enable_target_mode = 0;
2022                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2023
2024                         if(!ha->flags.host_shutting_down) 
2025                                 tgt_data.disable_lun(ha);
2026                         
2027                         goto out;
2028                 }
2029
2030                 tgt = ha->tgt;
2031                 ha->tgt = NULL; /* ensure no one gets in behind us */
2032                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2033
2034                 TRACE_DBG("Shutting down host %ld(%ld,%p)",
2035                           ha->host_no, ha->instance, ha);
2036                 scst_unregister(tgt->scst_tgt);
2037                 /* free of tgt happens via callback q2t_target_release
2038                  * called from scst_unregister, so we shouldn't touch it again 
2039                  */
2040                 tgt = NULL;
2041                 break;
2042
2043         default :
2044                 printk("%s: Reached default case of enumish switch statment %d",
2045                        __func__, action);
2046         }
2047
2048 out:
2049         TRACE_EXIT();
2050         return;
2051 }
2052
2053 #if defined(DEBUG) || defined(TRACING)
2054
2055 #define Q2T_PROC_LOG_ENTRY_NAME     "trace_level"
2056
2057 #include <linux/proc_fs.h>
2058
2059 static int qla2x00t_proc_log_entry_read(char *buffer, char **start,
2060                                         off_t offset, int length, int *eof,
2061                                         void *data)
2062 {
2063         int res = 0;
2064
2065         TRACE_ENTRY();
2066         res = scst_proc_log_entry_read(buffer, start, offset, length, eof,
2067                                        data, trace_flag, NULL);
2068
2069         TRACE_EXIT_RES(res);
2070         return res;
2071 }
2072
2073 static int qla2x00t_proc_log_entry_write(struct file *file, const char *buf,
2074                                          unsigned long length, void *data)
2075 {
2076         int res = 0;
2077
2078         TRACE_ENTRY();
2079
2080         res = scst_proc_log_entry_write(file, buf, length, data,
2081                         &trace_flag, SCST_DEFAULT_QLA_LOG_FLAGS, NULL);
2082
2083         TRACE_EXIT_RES(res);
2084         return res;
2085 }
2086 #endif
2087
2088 static int qla2x00t_proc_log_entry_build(struct scst_tgt_template *templ)
2089 {
2090         int res = 0;
2091 #if defined(DEBUG) || defined(TRACING)
2092         struct proc_dir_entry *p, *root;
2093
2094         TRACE_ENTRY();
2095         root = scst_proc_get_tgt_root(templ);
2096
2097         if (root) {
2098                 /* create the proc file entry for the device */
2099                 p = create_proc_read_entry(Q2T_PROC_LOG_ENTRY_NAME,
2100                                            S_IFREG | S_IRUGO | S_IWUSR, root,
2101                                            qla2x00t_proc_log_entry_read,
2102                                            (void *)templ->name);
2103                 if (p == NULL) {
2104                         PRINT_ERROR("Not enough memory to register "
2105                              "target driver %s entry %s in /proc",
2106                               templ->name, Q2T_PROC_LOG_ENTRY_NAME);
2107                         res = -ENOMEM;
2108                         goto out;
2109                 }
2110                 p->write_proc = qla2x00t_proc_log_entry_write;
2111         }
2112
2113 out:
2114
2115         TRACE_EXIT_RES(res);
2116 #endif
2117         return res;
2118 }
2119
2120 static void qla2x00t_proc_log_entry_clean(struct scst_tgt_template *templ)
2121 {
2122 #if defined(DEBUG) || defined(TRACING)
2123         struct proc_dir_entry *root;
2124
2125         TRACE_ENTRY();
2126
2127         root = scst_proc_get_tgt_root(templ);
2128
2129         if (root) {
2130                 remove_proc_entry(Q2T_PROC_LOG_ENTRY_NAME, root);
2131         }
2132         TRACE_EXIT();
2133 #endif
2134 }
2135
2136 static int __init qla2x00t_init(void)
2137 {
2138         int res = 0;
2139
2140         TRACE_ENTRY();
2141
2142         q2t_cmd_cachep = kmem_cache_create("q2t_cmd_struct",
2143                                            sizeof(struct q2t_cmd),
2144                                            0, Q2T_CACHE_FLAGS, NULL, NULL);
2145         if (q2t_cmd_cachep == NULL) {
2146                 res = -ENOMEM;
2147                 goto out;
2148         }
2149         
2150         if (scst_register_target_template(&tgt_template) < 0) {
2151                 res = -ENODEV;
2152                 goto out;
2153         }
2154
2155         /* qla2xxx_tgt_register_driver() happens in q2t_target_detect 
2156          * called via scst_register_target_template()
2157          */
2158
2159         res = qla2x00t_proc_log_entry_build(&tgt_template);
2160         if (res < 0) {
2161                 goto out_unreg_target;
2162         }
2163
2164 out:
2165         TRACE_EXIT();
2166         return res;
2167
2168 out_unreg_target:
2169         scst_unregister_target_template(&tgt_template);
2170         qla2xxx_tgt_unregister_driver();
2171         goto out;
2172 }
2173
2174 static void __exit qla2x00t_exit(void)
2175 {
2176         TRACE_ENTRY();
2177
2178         qla2x00t_proc_log_entry_clean(&tgt_template);
2179
2180         scst_unregister_target_template(&tgt_template);
2181         
2182         qla2xxx_tgt_unregister_driver();
2183         
2184         kmem_cache_destroy(q2t_cmd_cachep);
2185
2186         TRACE_EXIT();
2187         return;
2188 }
2189
2190 module_init(qla2x00t_init);
2191 module_exit(qla2x00t_exit);
2192
2193 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar & Nathaniel Clark");
2194 MODULE_DESCRIPTION("Target mode logic for qla2xxx");
2195 MODULE_LICENSE("GPL");
2196 MODULE_VERSION(Q2T_VERSION_STRING);