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