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