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