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