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