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