4 * Copyright (C) 2004 - 2008 Vladislav Bolkhovitin <vst@vlnb.net>
5 * Copyright (C) 2004 - 2005 Leonid Stoljar
6 * Copyright (C) 2006 Nathaniel Clark <nate@misrule.us>
8 * QLogic 2x00 SCSI target driver.
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
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.
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>
36 /* Necessary to have equal structures with the initiator */
37 #if defined(FC_IP_SUPPORT)
39 #include <linux/if_arp.h>
40 #include <linux/skbuff.h>
46 #ifndef FC_TARGET_SUPPORT
47 #error "FC_TARGET_SUPPORT is NOT DEFINED"
50 #ifdef CONFIG_SCST_DEBUG
51 #define Q2T_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
52 TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | \
53 TRACE_MGMT_DEBUG | TRACE_MINOR | TRACE_SPECIAL)
55 # ifdef CONFIG_SCST_TRACING
56 #define Q2T_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | \
61 static int q2t_target_detect(struct scst_tgt_template *templ);
62 static int q2t_target_release(struct scst_tgt *scst_tgt);
63 static int q2t_xmit_response(struct scst_cmd *scst_cmd);
64 static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd);
65 static void q2t_on_free_cmd(struct scst_cmd *scst_cmd);
66 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd);
68 /* Predefs for callbacks handed to qla2xxx(target) */
69 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt);
70 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha,
72 static void q2t_ctio_completion(scsi_qla_host_t *ha, uint32_t handle);
73 static void q2t_host_action(scsi_qla_host_t *ha,
74 qla2x_tgt_host_action_t action);
75 static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
76 atio_entry_t *atio, int ha_locked);
82 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
83 #define trace_flag q2t_trace_flag
84 unsigned long q2t_trace_flag = Q2T_DEFAULT_LOG_FLAGS;
87 struct scst_tgt_template tgt_template = {
91 #ifdef DEBUG_WORK_IN_THREAD
92 xmit_response_atomic: 0,
93 rdy_to_xfer_atomic: 0,
95 xmit_response_atomic: 1,
96 rdy_to_xfer_atomic: 1,
98 detect: q2t_target_detect,
99 release: q2t_target_release,
100 xmit_response: q2t_xmit_response,
101 rdy_to_xfer: q2t_rdy_to_xfer,
102 on_free_cmd: q2t_on_free_cmd,
103 task_mgmt_fn_done: q2t_task_mgmt_fn_done,
106 struct kmem_cache *q2t_cmd_cachep = NULL;
107 static struct qla2x_tgt_target tgt_data;
113 static inline int test_tgt_sess_count(struct q2t_tgt *tgt, scsi_qla_host_t *ha)
119 * We need to protect against race, when tgt is freed before or
122 spin_lock_irqsave(&tgt->ha->hardware_lock, flags);
123 TRACE_DBG("tgt %p, empty(sess_list)=%d sess_count=%d",
124 tgt, list_empty(&tgt->sess_list), tgt->sess_count);
125 res = (tgt->sess_count == 0);
126 spin_unlock_irqrestore(&tgt->ha->hardware_lock, flags);
131 /* ha->hardware_lock supposed to be held on entry */
132 static inline void q2t_exec_queue(scsi_qla_host_t *ha)
134 tgt_data.isp_cmd(ha);
137 /* ha->hardware_lock supposed to be held on entry */
138 static void q2t_modify_command_count(scsi_qla_host_t *ha, int cmd_count,
141 modify_lun_entry_t *pkt;
145 TRACE_DBG("Sending MODIFY_LUN ha %p, cmd %d, imm %d",
146 ha, cmd_count, imm_count);
148 pkt = (modify_lun_entry_t *)tgt_data.req_pkt(ha);
149 ha->tgt->modify_lun_expected++;
151 pkt->entry_type = MODIFY_LUN_TYPE;
152 pkt->entry_count = 1;
154 pkt->operators = MODIFY_LUN_CMD_SUB; /* Subtract from command count */
155 pkt->command_count = -cmd_count;
156 } else if (cmd_count > 0){
157 pkt->operators = MODIFY_LUN_CMD_ADD; /* Add to command count */
158 pkt->command_count = cmd_count;
162 pkt->operators |= MODIFY_LUN_IMM_SUB;
163 pkt->immed_notify_count = -imm_count;
164 } else if (imm_count > 0) {
165 pkt->operators |= MODIFY_LUN_IMM_ADD;
166 pkt->immed_notify_count = imm_count;
169 pkt->timeout = 0; /* Use default */
176 /* ha->hardware_lock supposed to be held on entry */
177 static void __q2t_send_notify_ack(scsi_qla_host_t *ha,
178 uint16_t target_id, uint16_t status, uint16_t task_flags,
179 uint16_t seq_id, uint32_t add_flags, uint16_t resp_code,
180 int resp_code_valid, uint16_t ox_id)
186 /* Send marker if required */
187 if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
188 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
189 "failed", ha->instance);
193 ntfy = (nack_entry_t *)tgt_data.req_pkt(ha);
196 ha->tgt->notify_ack_expected++;
198 memset(ntfy, 0, sizeof(*ntfy));
199 ntfy->entry_type = NOTIFY_ACK_TYPE;
200 ntfy->entry_count = 1;
201 SET_TARGET_ID(ha, ntfy->target, target_id);
202 ntfy->status = status;
203 ntfy->task_flags = task_flags;
204 ntfy->seq_id = seq_id;
205 /* Do not increment here, the chip isn't decrementing */
206 /* ntfy->flags = __constant_cpu_to_le16(NOTIFY_ACK_RES_COUNT); */
207 ntfy->flags |= cpu_to_le16(add_flags);
210 if (resp_code_valid) {
211 ntfy->resp_code = cpu_to_le16(resp_code);
213 __constant_cpu_to_le16(NOTIFY_ACK_TM_RESP_CODE_VALID);
216 TRACE(TRACE_SCSI, "Sending Notify Ack Seq %#x -> I %#x St %#x RC %#x",
217 le16_to_cpu(seq_id), target_id, le16_to_cpu(status),
218 le16_to_cpu(ntfy->resp_code));
226 /* ha->hardware_lock supposed to be held on entry */
227 static inline void q2t_send_notify_ack(scsi_qla_host_t *ha,
228 notify_entry_t *iocb, uint32_t add_flags, uint16_t resp_code,
231 __q2t_send_notify_ack(ha, GET_TARGET_ID(ha, iocb), iocb->status,
232 iocb->task_flags, iocb->seq_id, add_flags, resp_code,
233 resp_code_valid, iocb->ox_id);
237 * register with initiator driver (but target mode isn't enabled till
238 * it's turned on via sysfs)
240 static int q2t_target_detect(struct scst_tgt_template *templ)
243 struct qla2x_tgt_initiator itd = {
244 magic:QLA2X_TARGET_MAGIC,
245 tgt_response_pkt:q2t_response_pkt,
246 tgt_ctio_completion:q2t_ctio_completion,
247 tgt_async_event:q2t_async_event,
248 tgt_host_action:q2t_host_action,
253 res = qla2xxx_tgt_register_driver(&itd, &tgt_data);
255 PRINT_ERROR("Unable to register driver: %d", res);
259 if (tgt_data.magic != QLA2X_INITIATOR_MAGIC) {
260 PRINT_ERROR("Wrong version of the initiator driver: %d",
271 static void q2t_free_session_done(struct scst_session *scst_sess)
273 struct q2t_sess *sess;
280 sBUG_ON(scst_sess == NULL);
281 sess = (struct q2t_sess *)scst_sess_get_tgt_priv(scst_sess);
282 sBUG_ON(sess == NULL);
290 TRACE_MGMT_DBG("tgt %p, empty(sess_list) %d, sess_count %d",
291 tgt, list_empty(&tgt->sess_list), tgt->sess_count);
296 * We need to protect against race, when tgt is freed before or
299 spin_lock_irqsave(&ha->hardware_lock, flags);
301 if (tgt->sess_count == 0)
302 wake_up_all(&tgt->waitQ);
303 spin_unlock_irqrestore(&ha->hardware_lock, flags);
310 /* ha->hardware_lock supposed to be held on entry */
311 static void q2t_unreg_sess(struct q2t_sess *sess)
318 list_del(&sess->list);
320 PRINT_INFO("qla2x00tgt(%ld): session for loop_id %d deleted",
321 sess->tgt->ha->instance, sess->loop_id);
324 * Any commands for this session will be finished regularly,
325 * because we must not drop SCSI commands on transport level,
326 * at least without any response to the initiator.
329 scst_unregister_session(sess->scst_sess, 0, q2t_free_session_done);
336 /* ha->hardware_lock supposed to be held on entry */
337 static void q2t_port_logout(scsi_qla_host_t *ha, int loop_id)
339 struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
341 TRACE_MGMT_DBG("scsi(%ld) Unregistering session %p loop_id=%d",
342 ha->host_no, sess, loop_id);
344 q2t_unreg_sess(sess);
347 /* ha->hardware_lock supposed to be held on entry */
348 static void q2t_clear_tgt_db(struct q2t_tgt *tgt)
350 struct q2t_sess *sess, *sess_tmp;
354 TRACE_MGMT_DBG("Clearing targets DB %p", tgt);
356 list_for_each_entry_safe(sess, sess_tmp, &tgt->sess_list, list) {
357 q2t_unreg_sess(sess);
360 /* At this point tgt could be already dead */
362 TRACE_MGMT_DBG("Finished clearing Target DB %p", tgt);
368 /* should be called w/out hardware_lock, but tgt should be
369 * unfindable at this point */
370 static int q2t_target_release(struct scst_tgt *scst_tgt)
373 struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
374 scsi_qla_host_t *ha = tgt->ha;
375 unsigned long flags = 0;
379 spin_lock_irqsave(&ha->hardware_lock, flags);
380 tgt->tgt_shutdown = 1;
381 q2t_clear_tgt_db(tgt);
382 spin_unlock_irqrestore(&ha->hardware_lock, flags);
384 wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha));
387 if(!ha->flags.host_shutting_down)
388 tgt_data.disable_lun(ha);
390 /* wait for sessions to clear out (just in case) */
391 wait_event(tgt->waitQ, test_tgt_sess_count(tgt, ha));
393 TRACE_MGMT_DBG("Finished waiting for tgt %p: empty(sess_list)=%d "
394 "sess_count=%d", tgt, list_empty(&tgt->sess_list),
397 /* The lock is needed, because we still can get an incoming packet */
398 spin_lock_irqsave(&ha->hardware_lock, flags);
399 scst_tgt_set_tgt_priv(scst_tgt, NULL);
401 spin_unlock_irqrestore(&ha->hardware_lock, flags);
409 static int q2t_pci_map_calc_cnt(struct q2t_prm *prm)
413 sBUG_ON(prm->sg_cnt == 0);
415 /* 32 bit S/G Data Transfer */
416 prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, prm->sg, prm->sg_cnt,
417 scst_to_tgt_dma_dir(prm->data_direction));
418 if (unlikely(prm->seg_cnt == 0))
421 * If greater than four sg entries then we need to allocate
422 * the continuation entries
424 if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) {
425 prm->req_cnt += (uint16_t)(prm->seg_cnt -
426 prm->tgt->datasegs_per_cmd) /
427 prm->tgt->datasegs_per_cont;
428 if (((uint16_t)(prm->seg_cnt - prm->tgt->datasegs_per_cmd)) %
429 prm->tgt->datasegs_per_cont)
436 TRACE_DBG("seg_cnt=%d, req_cnt=%d, res=%d", prm->seg_cnt,
441 PRINT_ERROR("qla2x00tgt(%ld): PCI mapping failed: sg_cnt=%d",
442 prm->tgt->ha->instance, prm->sg_cnt);
447 /* ha->hardware_lock supposed to be held on entry */
448 static inline uint32_t q2t_make_handle(scsi_qla_host_t *ha)
453 /* always increment cmd handle */
456 if (h > MAX_OUTSTANDING_COMMANDS) {
459 if (h == ha->current_cmd) {
460 TRACE(TRACE_OUT_OF_MEM, "Ran out of empty cmd slots "
465 } while ((h == Q2T_NULL_HANDLE) ||
466 (h == Q2T_BUSY_HANDLE) ||
467 (h == Q2T_SKIP_HANDLE) ||
468 (ha->cmds[h] != NULL));
470 if (h != Q2T_NULL_HANDLE)
476 /* ha->hardware_lock supposed to be held on entry */
478 * NOTE: About CTIO_COMPLETION_HANDLE
479 * This is checked for in qla2x00_process_response_queue() to see
480 * if a handle coming back in a multi-complete should come to the tgt driver
481 * or be handled there by qla2xxx
483 static void q2t_build_ctio_pkt(struct q2t_prm *prm)
488 prm->pkt = (ctio_common_entry_t *)tgt_data.req_pkt(prm->tgt->ha);
490 if (prm->tgt->tgt_enable_64bit_addr)
491 prm->pkt->entry_type = CTIO_A64_TYPE;
493 prm->pkt->entry_type = CONTINUE_TGT_IO_TYPE;
495 prm->pkt->entry_count = (uint8_t) prm->req_cnt;
497 h = q2t_make_handle(prm->tgt->ha);
498 if (h != Q2T_NULL_HANDLE) {
499 prm->tgt->ha->cmds[h] = prm->cmd;
501 prm->pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
503 timeout = Q2T_TIMEOUT;
504 prm->pkt->timeout = cpu_to_le16(timeout);
506 /* Set initiator ID */
507 h = GET_TARGET_ID(prm->tgt->ha, &prm->cmd->atio);
508 SET_TARGET_ID(prm->tgt->ha, prm->pkt->target, h);
510 prm->pkt->exchange_id = prm->cmd->atio.exchange_id;
512 TRACE(TRACE_DEBUG|TRACE_SCSI,
513 "handle(scst_cmd) -> %08x, timeout %d L %#x -> I %#x E %#x",
514 prm->pkt->handle, timeout, le16_to_cpu(prm->cmd->atio.lun),
515 GET_TARGET_ID(prm->tgt->ha, prm->pkt),
516 le16_to_cpu(prm->pkt->exchange_id));
520 static void q2t_load_data_segments(struct q2t_prm *prm)
524 int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
526 TRACE_DBG("iocb->scsi_status=%x, iocb->flags=%x",
527 le16_to_cpu(prm->pkt->scsi_status), le16_to_cpu(prm->pkt->flags));
529 prm->pkt->transfer_length = cpu_to_le32(prm->bufflen);
531 /* Setup packet address segment pointer */
532 dword_ptr = prm->pkt->dseg_0_address;
534 if (prm->seg_cnt == 0) {
535 /* No data transfer */
539 TRACE_BUFFER("No data, CTIO packet data",
540 prm->pkt, REQUEST_ENTRY_SIZE);
544 /* Set total data segment count */
545 prm->pkt->dseg_count = cpu_to_le16(prm->seg_cnt);
547 /* If scatter gather */
548 TRACE_SG("%s", "Building S/G data segments...");
549 /* Load command entry data segments */
551 (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt;
552 cnt++, prm->seg_cnt--)
555 cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
556 if (enable_64bit_addressing) {
558 cpu_to_le32(pci_dma_hi32
559 (sg_dma_address(prm->sg)));
561 *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
563 TRACE_SG("S/G Segment phys_addr=%llx:%llx, len=%d",
564 (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
565 (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
566 (int)sg_dma_len(prm->sg));
571 TRACE_BUFFER("Scatter/gather, CTIO packet data",
572 prm->pkt, REQUEST_ENTRY_SIZE);
574 /* Build continuation packets */
575 while (prm->seg_cnt > 0) {
576 cont_a64_entry_t *cont_pkt64 =
577 (cont_a64_entry_t *)tgt_data.req_cont_pkt(prm->tgt->ha);
580 * Make sure that from cont_pkt64 none of
581 * 64-bit specific fields used for 32-bit
582 * addressing. Cast to (cont_entry_t*) for
586 memset(cont_pkt64, 0, sizeof(*cont_pkt64));
588 cont_pkt64->entry_count = 1;
589 cont_pkt64->sys_define = 0;
591 if (enable_64bit_addressing) {
592 cont_pkt64->entry_type = CONTINUE_A64_TYPE;
594 (uint32_t*)&cont_pkt64->dseg_0_address;
596 cont_pkt64->entry_type = CONTINUE_TYPE;
598 (uint32_t*)&((cont_entry_t *)
599 cont_pkt64)->dseg_0_address;
602 /* Load continuation entry data segments */
604 cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt;
605 cnt++, prm->seg_cnt--)
608 cpu_to_le32(pci_dma_lo32
609 (sg_dma_address(prm->sg)));
610 if (enable_64bit_addressing) {
612 cpu_to_le32(pci_dma_hi32
616 *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
618 TRACE_SG("S/G Segment Cont. phys_addr=%llx:%llx, len=%d",
619 (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)),
620 (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)),
621 (int)sg_dma_len(prm->sg));
626 TRACE_BUFFER("Continuation packet data",
627 cont_pkt64, REQUEST_ENTRY_SIZE);
634 static void q2t_init_ctio_ret_entry(ctio_ret_entry_t *ctio_m1,
639 prm->sense_buffer_len = min((uint32_t)prm->sense_buffer_len,
640 (uint32_t)sizeof(ctio_m1->sense_data));
642 ctio_m1->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
643 OF_NO_DATA | OF_SS_MODE_1);
644 ctio_m1->flags |= __constant_cpu_to_le16(OF_INC_RC);
645 ctio_m1->scsi_status = cpu_to_le16(prm->rq_result);
646 ctio_m1->residual = cpu_to_le32(prm->residual);
647 if (SCST_SENSE_VALID(prm->sense_buffer)) {
648 ctio_m1->scsi_status |=
649 __constant_cpu_to_le16(SS_SENSE_LEN_VALID);
650 ctio_m1->sense_length = cpu_to_le16(prm->sense_buffer_len);
651 memcpy(ctio_m1->sense_data, prm->sense_buffer,
652 prm->sense_buffer_len);
654 memset(ctio_m1->sense_data, 0, sizeof(ctio_m1->sense_data));
655 ctio_m1->sense_length = 0;
658 TRACE_BUFFER("CTIO returned packet data", ctio_m1, REQUEST_ENTRY_SIZE);
660 /* Sense with len > 26, is it possible ??? */
666 static inline int q2t_has_data(struct scst_cmd *scst_cmd)
668 return scst_cmd_get_resp_data_len(scst_cmd) > 0;
671 static int q2t_xmit_response(struct scst_cmd *scst_cmd)
673 int res = SCST_TGT_RES_SUCCESS;
674 struct q2t_sess *sess;
676 unsigned long flags = 0;
677 struct q2t_prm prm = { 0 };
678 int data_sense_flag = 0;
679 uint16_t full_req_cnt;
682 TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd));
684 #ifdef DEBUG_WORK_IN_THREAD
685 if (scst_cmd_atomic(scst_cmd))
686 return SCST_TGT_RES_NEED_THREAD_CTX;
689 prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
690 sess = (struct q2t_sess *)
691 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
693 if (unlikely(scst_cmd_aborted(scst_cmd))) {
694 scsi_qla_host_t *ha = sess->tgt->ha;
696 TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): terminating exchange "
697 "for aborted scst_cmd=%p (tag=%Ld)",
698 ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd));
700 scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED);
702 prm.cmd->state = Q2T_STATE_ABORTED;
704 q2t_send_term_exchange(ha, prm.cmd, &prm.cmd->atio, 0);
705 /* !! At this point cmd could be already freed !! */
709 prm.sg = scst_cmd_get_sg(scst_cmd);
710 prm.bufflen = scst_cmd_get_resp_data_len(scst_cmd);
711 prm.sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
712 prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
713 prm.rq_result = scst_cmd_get_status(scst_cmd);
714 prm.sense_buffer = scst_cmd_get_sense_buffer(scst_cmd);
715 prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
719 is_send_status = scst_cmd_get_is_send_status(scst_cmd);
721 TRACE_DBG("rq_result=%x, is_send_status=%x", prm.rq_result,
724 if (prm.rq_result != 0)
725 TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
727 if (!is_send_status) {
728 /* ToDo, after it's done in SCST */
729 PRINT_ERROR("qla2x00tgt(%ld): is_send_status not set: "
730 "feature not implemented", prm.tgt->ha->instance);
731 res = SCST_TGT_RES_FATAL_ERROR;
735 /* Acquire ring specific lock */
736 spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
738 /* Send marker if required */
739 if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
740 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
741 "failed", prm.tgt->ha->instance);
742 res = SCST_TGT_RES_FATAL_ERROR;
746 TRACE_DBG("CTIO start: ha(%d)", (int) prm.tgt->ha->instance);
748 if (q2t_has_data(scst_cmd)) {
749 if (q2t_pci_map_calc_cnt(&prm) != 0) {
750 res = SCST_TGT_RES_QUEUE_FULL;
753 full_req_cnt = prm.req_cnt;
754 if (SCST_SENSE_VALID(prm.sense_buffer)) {
759 full_req_cnt = prm.req_cnt;
761 q2t_build_ctio_pkt(&prm);
763 if (prm.data_direction != SCST_DATA_WRITE) {
765 le32_to_cpu(prm.cmd->atio.data_length) - prm.bufflen;
766 if (prm.residual > 0) {
767 TRACE_DBG("Residual underflow: %d", prm.residual);
768 prm.rq_result |= SS_RESIDUAL_UNDER;
769 } else if (prm.residual < 0) {
770 TRACE_DBG("Residual overflow: %d", prm.residual);
771 prm.rq_result |= SS_RESIDUAL_OVER;
772 prm.residual = -prm.residual;
775 if (q2t_has_data(scst_cmd)) {
776 prm.pkt->flags |= __constant_cpu_to_le16(
777 OF_FAST_POST | OF_INC_RC | OF_DATA_IN);
779 q2t_load_data_segments(&prm);
781 if (data_sense_flag == 0) {
782 prm.pkt->scsi_status = cpu_to_le16(
784 prm.pkt->residual = cpu_to_le32(prm.residual);
786 __constant_cpu_to_le16(OF_SSTS);
788 ctio_ret_entry_t *ctio_m1 =
790 tgt_data.req_cont_pkt(prm.tgt->ha);
792 TRACE_DBG("%s", "Building additional status "
795 memcpy(ctio_m1, prm.pkt, sizeof(*ctio_m1));
796 ctio_m1->entry_count = 1;
798 /* Real finish is ctio_m1's finish */
799 prm.pkt->handle = Q2T_SKIP_HANDLE |
800 CTIO_COMPLETION_HANDLE_MARK;
802 prm.pkt->flags &= ~__constant_cpu_to_le16(OF_INC_RC);
804 q2t_init_ctio_ret_entry(ctio_m1, &prm);
805 TRACE_BUFFER("Status CTIO packet data", ctio_m1,
809 q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
811 q2t_init_ctio_ret_entry((ctio_ret_entry_t *)prm.pkt, &prm);
814 prm.cmd->state = Q2T_STATE_PROCESSED; /* Mid-level is done processing */
816 TRACE_BUFFER("Xmitting", prm.pkt, REQUEST_ENTRY_SIZE);
818 q2t_exec_queue(prm.tgt->ha);
821 /* Release ring specific lock */
822 spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
829 static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
831 int res = SCST_TGT_RES_SUCCESS;
832 struct q2t_sess *sess;
833 unsigned long flags = 0;
834 struct q2t_prm prm = { 0 };
837 TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd));
839 #ifdef DEBUG_WORK_IN_THREAD
840 if (scst_cmd_atomic(scst_cmd))
841 return SCST_TGT_RES_NEED_THREAD_CTX;
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));
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);
855 /* Acquire ring specific lock */
856 spin_lock_irqsave(&prm.tgt->ha->hardware_lock, flags);
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->instance);
862 res = SCST_TGT_RES_FATAL_ERROR;
866 TRACE_DBG("CTIO_start: ha(%d)", (int) prm.tgt->ha->instance);
868 /* Calculate number of entries and segments required */
869 if (q2t_pci_map_calc_cnt(&prm) != 0) {
870 res = SCST_TGT_RES_QUEUE_FULL;
874 prm.cmd->iocb_cnt = prm.req_cnt;
876 q2t_build_ctio_pkt(&prm);
878 prm.pkt->flags = __constant_cpu_to_le16(OF_FAST_POST | OF_DATA_OUT);
880 q2t_load_data_segments(&prm);
882 prm.cmd->state = Q2T_STATE_NEED_DATA;
884 TRACE_BUFFER("Xfering", prm.pkt, REQUEST_ENTRY_SIZE);
886 q2t_exec_queue(prm.tgt->ha);
889 /* Release ring specific lock */
890 spin_unlock_irqrestore(&prm.tgt->ha->hardware_lock, flags);
896 static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
897 atio_entry_t *atio, int ha_locked)
899 ctio_ret_entry_t *ctio;
900 unsigned long flags = 0;
901 int do_tgt_cmd_done = 0;
905 TRACE_DBG("Sending TERM EXCH CTIO (ha=%p)", ha);
908 spin_lock_irqsave(&ha->hardware_lock, flags);
910 /* Send marker if required */
911 if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
912 PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
913 "failed", ha->instance);
917 ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
919 PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
920 "request packet", ha->instance, __func__);
924 ctio->entry_type = CTIO_RET_TYPE;
925 ctio->entry_count = 1;
928 ctio->handle = q2t_make_handle(ha);
929 if (ctio->handle != Q2T_NULL_HANDLE) {
930 ha->cmds[ctio->handle] = cmd;
932 ctio->handle = Q2T_SKIP_HANDLE;
936 ctio->handle = Q2T_SKIP_HANDLE;
938 ctio->handle |= CTIO_COMPLETION_HANDLE_MARK;
940 SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
941 ctio->exchange_id = atio->exchange_id;
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;
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);
952 TRACE_BUFFER("CTIO TERM EXCH packet data", ctio, REQUEST_ENTRY_SIZE);
958 spin_unlock_irqrestore(&ha->hardware_lock, flags);
960 if (do_tgt_cmd_done) {
963 scst_tgt_cmd_done(cmd->scst_cmd);
964 /* !! At this point cmd could be already freed !! */
971 static inline void q2t_free_cmd(struct q2t_cmd *cmd)
973 kmem_cache_free(q2t_cmd_cachep, cmd);
976 static void q2t_on_free_cmd(struct scst_cmd *scst_cmd)
978 struct q2t_cmd *cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
981 TRACE(TRACE_SCSI, "END Command tag %Ld", scst_cmd_get_tag(scst_cmd));
983 scst_cmd_set_tgt_priv(scst_cmd, NULL);
991 /* ha->hardware_lock supposed to be held on entry */
992 static inline struct scst_cmd *q2t_get_cmd(scsi_qla_host_t *ha, uint32_t handle)
994 if (ha->cmds[handle] != NULL) {
995 struct scst_cmd *cmd = ha->cmds[handle]->scst_cmd;
996 ha->cmds[handle] = NULL;
1002 /* ha->hardware_lock supposed to be held on entry */
1003 static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
1006 ctio_common_entry_t *ctio)
1008 struct scst_cmd *scst_cmd;
1009 struct q2t_cmd *cmd;
1010 uint16_t loop_id = -1;
1016 loop_id = GET_TARGET_ID(ha, ctio);
1018 TRACE(TRACE_DEBUG|TRACE_SCSI, "handle(ctio %p status %#x) <- %08x I %x",
1019 ctio, status, handle, loop_id);
1021 /* Clear out CTIO_COMPLETION_HANDLE_MARK */
1022 handle &= ~CTIO_COMPLETION_HANDLE_MARK;
1024 if (status != CTIO_SUCCESS) {
1027 case CTIO_LIP_RESET:
1028 case CTIO_TARGET_RESET:
1031 case CTIO_INVALID_RX_ID:
1033 TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): CTIO with "
1034 "status %#x received (LIP_RESET=e, ABORTED=2, "
1035 "TARGET_RESET=17, TIMEOUT=b, "
1036 "INVALID_RX_ID=8)", ha->instance, status);
1039 case CTIO_PORT_LOGGED_OUT:
1040 case CTIO_PORT_UNAVAILABLE:
1041 PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED "
1042 "OUT (29) or PORT UNAVAILABLE (28) status %x "
1043 "received", ha->instance, status);
1047 PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status "
1048 "0x%x received", ha->instance, status);
1051 q2t_modify_command_count(ha, 1, 0);
1054 if (handle != Q2T_NULL_HANDLE) {
1055 if (unlikely(handle == Q2T_SKIP_HANDLE)) {
1058 if (unlikely(handle == Q2T_BUSY_HANDLE)) {
1061 scst_cmd = q2t_get_cmd(ha, handle);
1062 if (unlikely(scst_cmd == NULL)) {
1063 PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1064 "find the command with handle %x",
1065 ha->instance, handle);
1068 if (unlikely(err)) {
1069 TRACE_MGMT_DBG("Found by handle failed CTIO scst_cmd "
1070 "%p (op %x)", scst_cmd, scst_cmd->cdb[0]);
1072 } else if (ctio != NULL) {
1073 uint32_t tag = le16_to_cpu(ctio->exchange_id);
1074 struct q2t_sess *sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1077 PRINT_INFO("qla2x00tgt(%ld): Suspicious: "
1078 "ctio_completion for non-existing session "
1079 "(loop_id %d, tag %d)",
1080 ha->instance, loop_id, tag);
1084 scst_cmd = scst_find_cmd_by_tag(sess->scst_sess, tag);
1085 if (scst_cmd == NULL) {
1086 PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
1087 "find the command with tag %d (loop_id %d)",
1088 ha->instance, tag, loop_id);
1091 if (unlikely(err)) {
1092 TRACE_MGMT_DBG("Found by ctio failed CTIO scst_cmd %p "
1093 "(op %x)", scst_cmd, scst_cmd->cdb[0]);
1096 TRACE_DBG("Found scst_cmd %p", scst_cmd);
1100 cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1101 if (unlikely(err)) {
1102 TRACE(TRACE_MGMT_MINOR, "Failed CTIO state %d (err %x)",
1103 cmd->state, status);
1106 if (cmd->state == Q2T_STATE_PROCESSED) {
1107 TRACE_DBG("Command %p finished", cmd);
1108 if (q2t_has_data(scst_cmd)) {
1109 pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1110 scst_cmd_get_sg_cnt(scst_cmd),
1111 scst_to_tgt_dma_dir(
1112 scst_cmd_get_data_direction(scst_cmd)));
1115 } else if (cmd->state == Q2T_STATE_NEED_DATA) {
1116 int context = SCST_CONTEXT_TASKLET;
1117 int rx_status = SCST_RX_STATUS_SUCCESS;
1119 cmd->state = Q2T_STATE_DATA_IN;
1121 if (status != CTIO_SUCCESS)
1122 rx_status = SCST_RX_STATUS_ERROR;
1124 #ifdef DEBUG_WORK_IN_THREAD
1125 context = SCST_CONTEXT_THREAD;
1128 TRACE_DBG("Data received, context %x, rx_status %d",
1129 context, rx_status);
1131 pci_unmap_sg(ha->pdev, scst_cmd_get_sg(scst_cmd),
1132 scst_cmd_get_sg_cnt(scst_cmd),
1133 scst_to_tgt_dma_dir(
1134 scst_cmd_get_data_direction(scst_cmd)));
1136 scst_rx_data(scst_cmd, rx_status, context);
1137 } else if (cmd->state == Q2T_STATE_ABORTED) {
1138 TRACE_MGMT_DBG("Aborted command %p finished", cmd);
1141 PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should "
1142 "not return a CTIO complete", ha->instance, cmd->state);
1151 if (unlikely(err)) {
1152 TRACE_MGMT_DBG("%s", "Finishing failed CTIO");
1153 scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED);
1155 scst_tgt_cmd_done(scst_cmd);
1159 /* ha->hardware_lock supposed to be held on entry */
1160 /* called via callback from qla2xxx */
1161 static void q2t_ctio_completion(scsi_qla_host_t *ha, uint32_t handle)
1164 sBUG_ON(ha == NULL);
1166 if (ha->tgt != NULL) {
1167 q2t_do_ctio_completion(ha, handle,
1168 CTIO_SUCCESS, NULL);
1170 TRACE_DBG("CTIO, but target mode not enabled. ha %p handle %#x",
1177 /* ha->hardware_lock supposed to be held on entry */
1178 static void q2t_send_busy(scsi_qla_host_t *ha, atio_entry_t *atio)
1180 ctio_ret_entry_t *ctio;
1184 ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
1185 ctio->entry_type = CTIO_RET_TYPE;
1186 ctio->entry_count = 1;
1187 ctio->handle = Q2T_BUSY_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
1188 ctio->scsi_status = __constant_cpu_to_le16(BUSY << 1);
1189 ctio->residual = atio->data_length;
1190 if (ctio->residual != 0)
1191 ctio->scsi_status |= SS_RESIDUAL_UNDER;
1194 SET_TARGET_ID(ha, ctio->target, GET_TARGET_ID(ha, atio));
1195 ctio->exchange_id = atio->exchange_id;
1197 ctio->flags = __constant_cpu_to_le16(OF_SSTS | OF_FAST_POST |
1198 OF_NO_DATA | OF_SS_MODE_1);
1199 ctio->flags |= __constant_cpu_to_le16(OF_INC_RC);
1201 TRACE_BUFFER("CTIO BUSY packet data", ctio, REQUEST_ENTRY_SIZE);
1209 /* ha->hardware_lock is supposed to be held on entry */
1210 static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
1213 struct q2t_sess *sess = cmd->sess;
1215 scst_data_direction dir = SCST_DATA_NONE;
1220 /* make it be in network byte order */
1221 lun = swab16(cmd->atio.lun);
1222 cmd->scst_cmd = scst_rx_cmd(sess->scst_sess, (uint8_t *)&lun,
1223 sizeof(lun), cmd->atio.cdb, Q2T_MAX_CDB_LEN,
1226 if (cmd->scst_cmd == NULL) {
1227 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_cmd() failed for "
1228 "host %ld(%p)", ha->instance, ha->host_no, ha);
1233 scst_cmd_set_tag(cmd->scst_cmd, le16_to_cpu(cmd->atio.exchange_id));
1234 scst_cmd_set_tgt_priv(cmd->scst_cmd, cmd);
1236 if (cmd->atio.execution_codes & ATIO_EXEC_READ)
1237 dir = SCST_DATA_READ;
1238 else if (cmd->atio.execution_codes & ATIO_EXEC_WRITE)
1239 dir = SCST_DATA_WRITE;
1240 scst_cmd_set_expected(cmd->scst_cmd, dir,
1241 le32_to_cpu(cmd->atio.data_length));
1243 switch (cmd->atio.task_codes) {
1244 case ATIO_SIMPLE_QUEUE:
1245 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_SIMPLE;
1247 case ATIO_HEAD_OF_QUEUE:
1248 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE;
1250 case ATIO_ORDERED_QUEUE:
1251 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1253 case ATIO_ACA_QUEUE:
1254 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ACA;
1257 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_UNTAGGED;
1260 PRINT_ERROR("qla2x00tgt(%ld): Unknown task code %x, use "
1261 "ORDERED instead", ha->instance, cmd->atio.task_codes);
1262 cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
1266 #ifdef DEBUG_WORK_IN_THREAD
1267 context = SCST_CONTEXT_THREAD;
1269 context = SCST_CONTEXT_TASKLET;
1272 TRACE_DBG("Context %x", context);
1273 TRACE(TRACE_SCSI, "START Command (tag %Ld)", scst_cmd_get_tag(cmd->scst_cmd));
1274 scst_cmd_init_done(cmd->scst_cmd, context);
1277 TRACE_EXIT_RES(res);
1281 /* Called in SCST's thread context */
1282 static void q2t_alloc_session_done(struct scst_session *scst_sess,
1283 void *data, int result)
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;
1293 PRINT_INFO("qla2x00tgt(%ld): Session initialization failed",
1296 spin_lock_irqsave(&ha->hardware_lock, flags);
1297 q2t_unreg_sess(sess);
1298 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1305 static char *q2t_find_name(scsi_qla_host_t *ha, int loop_id)
1311 wwn_str = kmalloc(2*WWN_SIZE, GFP_ATOMIC);
1312 if (wwn_str == NULL) {
1313 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of wwn_str failed");
1317 /* Find the WWN in the port db given the loop_id */
1318 list_for_each_entry(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);
1331 if (wwn_found == 0) {
1332 TRACE_MGMT_DBG("qla2x00tgt(%ld): Unable to find wwn login for "
1333 "loop id %d", ha->instance, loop_id);
1342 static char *q2t_make_name(scsi_qla_host_t *ha, const uint8_t *name)
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");
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],
1359 /* ha->hardware_lock supposed to be held on entry */
1360 static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_entry_t *atio)
1363 struct q2t_tgt *tgt;
1364 struct q2t_sess *sess;
1365 struct q2t_cmd *cmd;
1372 loop_id = GET_TARGET_ID(ha, atio);
1374 pn = (uint16_t *)(((char *)atio)+0x2a);
1375 TRACE_DBG("To SCST instance=%ld l_id=%d tag=%d wwpn=%04x%04x%04x%04x",
1376 ha->instance, loop_id, le16_to_cpu(atio->exchange_id),
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)); */
1384 if (tgt->tgt_shutdown) {
1385 TRACE_MGMT_DBG("New command while device %p is shutting "
1391 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
1392 cmd = kmem_cache_alloc(q2t_cmd_cachep, GFP_ATOMIC);
1394 cmd = kmem_cache_zalloc(q2t_cmd_cachep, GFP_ATOMIC);
1397 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed");
1401 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
1402 memset(cmd, 0, sizeof(*cmd));
1405 TRACE_BUFFER("ATIO Coming Up", atio, sizeof(*atio));
1406 memcpy(&cmd->atio, atio, sizeof(*atio));
1407 cmd->state = Q2T_STATE_NEW;
1409 sess = q2t_find_sess_by_lid(tgt, loop_id);
1410 if (unlikely(sess == NULL)) {
1411 sess = kzalloc(sizeof(*sess), GFP_ATOMIC);
1413 TRACE(TRACE_OUT_OF_MEM, "%s",
1414 "Allocation of sess failed");
1420 sess->loop_id = loop_id;
1421 INIT_LIST_HEAD(&sess->list);
1423 /* register session (remote initiator) */
1427 name = q2t_find_name(ha, loop_id);
1429 name = q2t_make_name(ha,
1430 atio->initiator_port_name);
1437 sess->scst_sess = scst_register_session(
1438 tgt->scst_tgt, 1, name, sess,
1439 q2t_alloc_session_done);
1443 if (sess->scst_sess == NULL) {
1444 PRINT_ERROR("qla2x00tgt(%ld): scst_register_session() failed "
1445 "for host %ld(%p)", ha->instance, ha->host_no, ha);
1449 scst_sess_set_tgt_priv(sess->scst_sess, sess);
1451 /* add session data to host data structure */
1452 list_add(&sess->list, &tgt->sess_list);
1457 res = q2t_do_send_cmd_to_scst(ha, cmd);
1462 TRACE_EXIT_RES(res);
1468 if (tgt->sess_count == 0)
1469 wake_up_all(&tgt->waitQ);
1477 /* ha->hardware_lock supposed to be held on entry */
1478 static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
1480 int res = 0, rc = -1;
1481 struct q2t_mgmt_cmd *mcmd;
1482 struct q2t_tgt *tgt;
1483 struct q2t_sess *sess;
1490 loop_id = GET_TARGET_ID(ha, iocb);
1492 /* Make it be in network byte order */
1493 lun = swab16(iocb->lun);
1495 sess = q2t_find_sess_by_lid(tgt, loop_id);
1497 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task mgmt fn 0x%x for "
1498 "non-existant session", ha->instance, iocb->task_flags);
1503 mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1505 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1511 mcmd->notify_entry = *iocb;
1513 switch (iocb->task_flags) {
1514 case IMM_NTFY_CLEAR_ACA:
1515 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1516 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1517 (uint8_t *)&lun, sizeof(lun),
1521 case IMM_NTFY_TARGET_RESET:
1522 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1523 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1524 (uint8_t *)&lun, sizeof(lun),
1528 case IMM_NTFY_LUN_RESET:
1529 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1530 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1531 (uint8_t *)&lun, sizeof(lun),
1535 case IMM_NTFY_CLEAR_TS:
1536 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1537 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1538 (uint8_t *)&lun, sizeof(lun),
1542 case IMM_NTFY_ABORT_TS:
1543 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1544 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1545 (uint8_t *)&lun, sizeof(lun),
1550 PRINT_ERROR("qla2x00tgt(%ld): Unknown task mgmt fn 0x%x",
1551 ha->instance, iocb->task_flags);
1556 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_lun() failed: %d",
1563 TRACE_EXIT_RES(res);
1571 /* ha->hardware_lock supposed to be held on entry */
1572 static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
1575 struct q2t_mgmt_cmd *mcmd;
1576 struct q2t_sess *sess;
1582 loop_id = GET_TARGET_ID(ha, iocb);
1583 tag = le16_to_cpu(iocb->seq_id);
1585 sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
1587 TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task abort for unexisting "
1588 "session", ha->instance);
1593 mcmd = kzalloc(sizeof(*mcmd), GFP_ATOMIC);
1595 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1601 mcmd->notify_entry = *iocb;
1603 rc = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, tag,
1606 PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_tag() failed: %d",
1613 TRACE_EXIT_RES(res);
1622 static void q2t_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
1624 struct q2t_mgmt_cmd *mcmd;
1625 unsigned long flags;
1629 TRACE_MGMT_DBG("scst_mcmd (%p) status %#x state %#x", scst_mcmd,
1630 scst_mcmd->status, scst_mcmd->state);
1632 mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd);
1633 if (unlikely(mcmd == NULL)) {
1634 PRINT_ERROR("scst_mcmd %p tgt_spec is NULL", mcmd);
1638 spin_lock_irqsave(&mcmd->sess->tgt->ha->hardware_lock, flags);
1639 q2t_send_notify_ack(mcmd->sess->tgt->ha, &mcmd->notify_entry, 0,
1640 (scst_mgmt_cmd_get_status(scst_mcmd) == SCST_MGMT_STATUS_SUCCESS)
1641 ? 0 : FC_TM_FAILED, 1);
1642 spin_unlock_irqrestore(&mcmd->sess->tgt->ha->hardware_lock, flags);
1644 /* scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); */
1645 scst_mcmd->tgt_priv = NULL;
1653 /* ha->hardware_lock supposed to be held on entry */
1654 static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
1658 uint32_t add_flags = 0;
1659 int send_notify_ack = 1;
1663 status = le16_to_cpu(iocb->status);
1664 loop_id = GET_TARGET_ID(ha, iocb);
1666 if (!ha->flags.enable_target_mode || ha->tgt == NULL) {
1667 TRACE(TRACE_MGMT_DEBUG|TRACE_SCSI|TRACE_DEBUG,
1668 "Acking %04x S %04x I %#x -> L %#x", status,
1669 le16_to_cpu(iocb->seq_id), loop_id,
1670 le16_to_cpu(iocb->lun));
1674 TRACE_BUFFER("IMMED Notify Coming Up", iocb, sizeof(*iocb));
1677 case IMM_NTFY_LIP_RESET:
1678 TRACE(TRACE_MGMT, "LIP reset (I %#x)", loop_id);
1680 * ToDo: doing so we reset all holding RESERVE'ations,
1681 * which could be unexpected, so be more carefull here
1683 q2t_clear_tgt_db(ha->tgt);
1684 /* set the Clear LIP reset event flag */
1685 add_flags |= NOTIFY_ACK_CLEAR_LIP_RESET;
1688 case IMM_NTFY_IOCB_OVERFLOW:
1689 PRINT_ERROR("qla2x00tgt(%ld): Cannot provide requested "
1690 "capability (IOCB overflow)", ha->instance);
1693 case IMM_NTFY_ABORT_TASK:
1694 TRACE(TRACE_MGMT_MINOR, "Abort Task (S %04x I %#x -> L %#x)",
1695 le16_to_cpu(iocb->seq_id), loop_id,
1696 le16_to_cpu(iocb->lun));
1697 if (q2t_abort_task(ha, iocb) == 0)
1698 send_notify_ack = 0;
1701 case IMM_NTFY_PORT_LOGOUT:
1702 TRACE(TRACE_MGMT, "Port logout (S %04x I %#x -> L %#x)",
1703 le16_to_cpu(iocb->seq_id), loop_id,
1704 le16_to_cpu(iocb->lun));
1706 * ToDo: doing so we reset all holding RESERVE'ations,
1707 * which could be unexpected, so be more carefull here
1709 q2t_port_logout(ha, loop_id);
1712 case IMM_NTFY_PORT_CONFIG:
1713 case IMM_NTFY_GLBL_TPRLO:
1714 case IMM_NTFY_GLBL_LOGO:
1715 /* ToDo: ports DB changes handling ?? */
1716 TRACE(TRACE_MGMT, "Port config changed, Global TPRLO or "
1717 "Global LOGO (%d)", status);
1719 * ToDo: doing so we reset all holding RESERVE'ations,
1720 * which could be unexpected, so be more carefull here
1722 q2t_clear_tgt_db(ha->tgt);
1725 case IMM_NTFY_RESOURCE:
1726 PRINT_ERROR("qla2x00tgt(%ld): Out of resources, host %ld",
1727 ha->instance, ha->host_no);
1730 case IMM_NTFY_MSG_RX:
1731 TRACE(TRACE_MGMT, "Immediate notify task %x", iocb->task_flags);
1732 if (q2t_handle_task_mgmt(ha, iocb) == 0)
1733 send_notify_ack = 0;
1737 PRINT_ERROR("qla2x00tgt(%ld): Received unknown immediate "
1738 "notify status %x", ha->instance, status);
1744 if (send_notify_ack)
1745 q2t_send_notify_ack(ha, iocb, add_flags, 0, 0);
1751 /* ha->hardware_lock supposed to be held on entry */
1752 /* called via callback from qla2xxx */
1753 static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
1759 TRACE(TRACE_SCSI, "pkt %p: T %02x C %02x S %02x handle %#x",
1760 pkt, pkt->entry_type, pkt->entry_count, pkt->entry_status,
1763 if (unlikely(ha->tgt == NULL)) {
1764 TRACE_DBG("response pkt, but no tgt. ha %p tgt_flag %d",
1765 ha, ha->flags.enable_target_mode);
1769 if (pkt->entry_status != 0) {
1770 PRINT_ERROR("qla2x00tgt(%ld): Received response packet %x "
1771 "with error status %x", ha->instance, pkt->entry_type,
1776 switch (pkt->entry_type) {
1777 case ACCEPT_TGT_IO_TYPE:
1778 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1780 atio = (atio_entry_t *)pkt;
1781 TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x "
1782 "lun %04x read/write %d data_length %08x "
1783 "target_id %02x exchange_id %04x ",
1784 ha->instance, le16_to_cpu(atio->status),
1785 le16_to_cpu(atio->lun),
1786 atio->execution_codes,
1787 le32_to_cpu(atio->data_length),
1788 GET_TARGET_ID(ha, atio),
1789 le16_to_cpu(atio->exchange_id));
1791 __constant_cpu_to_le16(ATIO_CDB_VALID)) {
1792 PRINT_ERROR("qla2x00tgt(%ld): ATIO with error "
1793 "status %x received", ha->instance,
1794 le16_to_cpu(atio->status));
1797 PRINT_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb,
1799 rc = q2t_send_cmd_to_scst(ha, atio);
1800 if (unlikely(rc != 0)) {
1802 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
1803 q2t_send_busy(ha, atio);
1805 q2t_send_term_exchange(ha, NULL, atio, 1);
1808 if (!ha->tgt->tgt_shutdown) {
1809 PRINT_INFO("qla2x00tgt(%ld): Unable to "
1810 "send the command to SCSI target "
1811 "mid-level, sending BUSY status",
1814 q2t_send_busy(ha, atio);
1817 } else if (!ha->tgt->tgt_shutdown) {
1818 PRINT_ERROR("qla2x00tgt(%ld): ATIO, but target mode "
1819 "disabled", ha->instance);
1823 case CONTINUE_TGT_IO_TYPE:
1824 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1825 ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1826 TRACE_DBG("CONTINUE_TGT_IO: instance %ld",
1828 q2t_do_ctio_completion(ha, entry->handle,
1829 le16_to_cpu(entry->status),
1831 } else if (!ha->tgt->tgt_shutdown) {
1832 PRINT_ERROR("qla2x00tgt(%ld): CTIO, but target mode "
1833 "disabled", ha->instance);
1838 if (ha->flags.enable_target_mode && ha->tgt != NULL) {
1839 ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
1840 TRACE_DBG("CTIO_A64: instance %ld", ha->instance);
1841 q2t_do_ctio_completion(ha, entry->handle,
1842 le16_to_cpu(entry->status),
1844 } else if (!ha->tgt->tgt_shutdown) {
1845 PRINT_ERROR("qla2x00tgt(%ld): CTIO_A64, but target "
1846 "mode disabled", ha->instance);
1850 case IMMED_NOTIFY_TYPE:
1851 TRACE_DBG("%s", "IMMED_NOTIFY");
1852 q2t_handle_imm_notify(ha, (notify_entry_t *)pkt);
1855 case NOTIFY_ACK_TYPE:
1856 if (ha->tgt == NULL) {
1857 PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK recieved "
1858 "with NULL tgt", ha->instance);
1859 } else if (ha->tgt->notify_ack_expected > 0) {
1860 nack_entry_t *entry = (nack_entry_t *)pkt;
1861 TRACE_DBG("NOTIFY_ACK seq %04x status %x",
1862 le16_to_cpu(entry->seq_id),
1863 le16_to_cpu(entry->status));
1864 ha->tgt->notify_ack_expected--;
1865 if (entry->status !=
1866 __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) {
1867 PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK "
1868 "failed %x", ha->instance,
1869 le16_to_cpu(entry->status));
1872 PRINT_ERROR("qla2x00tgt(%ld): Unexpected NOTIFY_ACK "
1873 "received", ha->instance);
1877 case MODIFY_LUN_TYPE:
1878 if ((ha->tgt != NULL) && (ha->tgt->modify_lun_expected > 0)) {
1879 struct q2t_tgt *tgt = ha->tgt;
1880 modify_lun_entry_t *entry = (modify_lun_entry_t *)pkt;
1881 TRACE_DBG("MODIFY_LUN %x, imm %c%d, cmd %c%d",
1883 (entry->operators & MODIFY_LUN_IMM_ADD) ?'+'
1884 :(entry->operators & MODIFY_LUN_IMM_SUB) ?'-'
1886 entry->immed_notify_count,
1887 (entry->operators & MODIFY_LUN_CMD_ADD) ?'+'
1888 :(entry->operators & MODIFY_LUN_CMD_SUB) ?'-'
1890 entry->command_count);
1891 tgt->modify_lun_expected--;
1892 if (entry->status != MODIFY_LUN_SUCCESS) {
1893 PRINT_ERROR("qla2x00tgt(%ld): MODIFY_LUN "
1894 "failed %x", ha->instance,
1897 tgt->disable_lun_status = entry->status;
1899 PRINT_ERROR("qla2x00tgt(%ld): Unexpected MODIFY_LUN "
1900 "received", (ha != NULL) ?ha->instance :-1);
1904 case ENABLE_LUN_TYPE:
1905 if (ha->tgt != NULL) {
1906 struct q2t_tgt *tgt = ha->tgt;
1907 elun_entry_t *entry = (elun_entry_t *)pkt;
1908 TRACE_DBG("ENABLE_LUN %x imm %u cmd %u ",
1909 entry->status, entry->immed_notify_count,
1910 entry->command_count);
1911 if ((ha->flags.enable_target_mode) &&
1912 (entry->status == ENABLE_LUN_ALREADY_ENABLED)) {
1913 TRACE_DBG("LUN is already enabled: %#x",
1915 entry->status = ENABLE_LUN_SUCCESS;
1916 } else if (entry->status == ENABLE_LUN_RC_NONZERO) {
1917 TRACE_DBG("ENABLE_LUN succeeded, but with "
1918 "error: %#x", entry->status);
1919 entry->status = ENABLE_LUN_SUCCESS;
1920 } else if (entry->status != ENABLE_LUN_SUCCESS) {
1921 PRINT_ERROR("qla2x00tgt(%ld): ENABLE_LUN "
1923 ha->instance, entry->status);
1924 ha->flags.enable_target_mode =
1925 ~ha->flags.enable_target_mode;
1926 } /* else success */
1927 tgt->disable_lun_status = entry->status;
1932 PRINT_INFO("qla2x00tgt(%ld): Received unknown response pkt "
1933 "type %x", ha->instance, pkt->entry_type);
1942 /* ha->hardware_lock supposed to be held on entry */
1943 /* called via callback from qla2xxx */
1944 static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha, uint16_t *mailbox)
1948 sBUG_ON(ha == NULL);
1950 if (unlikely(ha->tgt == NULL)) {
1951 TRACE(TRACE_DEBUG|TRACE_MGMT,
1952 "ASYNC EVENT %#x, but no tgt. ha %p tgt_flag %d",
1953 code, ha, ha->flags.enable_target_mode);
1958 case MBA_RESET: /* Reset */
1959 case MBA_SYSTEM_ERR: /* System Error */
1960 case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
1961 case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
1963 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
1964 case MBA_LIP_RESET: /* LIP reset occurred */
1965 case MBA_POINT_TO_POINT: /* Point to point mode. */
1966 case MBA_CHG_IN_CONNECTION: /* Change in connection mode. */
1967 TRACE_MGMT_DBG("Async event %#x occured: clear tgt_db", code);
1970 * ToDo: doing so we reset all holding RESERVE'ations,
1971 * which could be unexpected, so be more carefull here
1973 q2t_clear_tgt_db(ha->tgt);
1976 case MBA_RSCN_UPDATE:
1977 TRACE_MGMT_DBG("RSCN Update (%x) N_Port %#06x (fmt %x)",
1978 code, ((mailbox[1]&0xF)<<2)|le16_to_cpu(mailbox[2]),
1979 (mailbox[1]&0xF0)>>1);
1982 case MBA_PORT_UPDATE: /* Port database update occurred */
1983 TRACE_MGMT_DBG("Port DB Chng: L_ID %#4x did %d: ignore",
1984 le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]));
1989 TRACE_MGMT_DBG("Async event %#x occured: ignore", code);
1990 /* just don't DO anything */
1999 static int q2t_get_target_name(scsi_qla_host_t *ha, char **wwn)
2001 const int wwn_len = 3*WWN_SIZE+2;
2005 name = kmalloc(wwn_len, GFP_KERNEL);
2007 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt name failed");
2012 sprintf(name, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
2013 ha->port_name[0], ha->port_name[1],
2014 ha->port_name[2], ha->port_name[3],
2015 ha->port_name[4], ha->port_name[5],
2016 ha->port_name[6], ha->port_name[7]);
2024 /* no lock held on entry */
2025 /* called via callback from qla2xxx */
2026 static void q2t_host_action(scsi_qla_host_t *ha,
2027 qla2x_tgt_host_action_t action)
2029 struct q2t_tgt *tgt = NULL;
2030 unsigned long flags = 0;
2035 sBUG_ON(ha == NULL);
2038 case ENABLE_TARGET_MODE:
2043 tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
2045 TRACE(TRACE_OUT_OF_MEM, "%s",
2046 "Allocation of tgt failed");
2051 tgt->disable_lun_status = Q2T_DISABLE_LUN_STATUS_NOT_SET;
2052 INIT_LIST_HEAD(&tgt->sess_list);
2053 init_waitqueue_head(&tgt->waitQ);
2055 if (ha->flags.enable_64bit_addressing) {
2056 PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
2057 "Addressing Enabled", ha->instance);
2058 tgt->tgt_enable_64bit_addr = 1;
2061 QLA_MAX_SG64(ha->request_q_length - 3);
2062 tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
2063 tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
2065 PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
2066 "PCI Addressing", ha->instance);
2068 QLA_MAX_SG32(ha->request_q_length - 3);
2069 tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
2070 tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
2073 if (q2t_get_target_name(ha, &wwn) != 0) {
2078 tgt->scst_tgt = scst_register(&tgt_template, wwn);
2080 if (!tgt->scst_tgt) {
2081 PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
2082 "failed for host %ld(%p)", ha->instance,
2088 scst_tgt_set_sg_tablesize(tgt->scst_tgt, sg_tablesize);
2089 scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
2091 spin_lock_irqsave(&ha->hardware_lock, flags);
2093 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2095 TRACE_DBG("Enable lun for host %ld(%ld,%p)",
2096 ha->host_no, ha->instance, ha);
2097 tgt_data.enable_lun(ha);
2101 case DISABLE_TARGET_MODE:
2102 spin_lock_irqsave(&ha->hardware_lock, flags);
2103 if (ha->tgt == NULL) {
2104 /* ensure target mode is marked as off */
2105 ha->flags.enable_target_mode = 0;
2106 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2108 if(!ha->flags.host_shutting_down)
2109 tgt_data.disable_lun(ha);
2115 ha->tgt = NULL; /* ensure no one gets in behind us */
2116 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2118 TRACE_DBG("Shutting down host %ld(%ld,%p)",
2119 ha->host_no, ha->instance, ha);
2120 scst_unregister(tgt->scst_tgt);
2122 * Free of tgt happens via callback q2t_target_release
2123 * called from scst_unregister, so we shouldn't touch it again
2129 PRINT_ERROR("Unknown action %d", action);
2138 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
2140 #define Q2T_PROC_LOG_ENTRY_NAME "trace_level"
2142 #include <linux/proc_fs.h>
2144 static int q2t_log_info_show(struct seq_file *seq, void *v)
2150 res = scst_proc_log_entry_read(seq, trace_flag, NULL);
2152 TRACE_EXIT_RES(res);
2156 static ssize_t q2t_proc_log_entry_write(struct file *file,
2157 const char __user *buf, size_t length, loff_t *off)
2163 res = scst_proc_log_entry_write(file, buf, length, &trace_flag,
2164 Q2T_DEFAULT_LOG_FLAGS, NULL);
2166 TRACE_EXIT_RES(res);
2170 static struct scst_proc_data q2t_log_proc_data = {
2171 SCST_DEF_RW_SEQ_OP(q2t_proc_log_entry_write)
2172 .show = q2t_log_info_show,
2176 static int q2t_proc_log_entry_build(struct scst_tgt_template *templ)
2179 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
2180 struct proc_dir_entry *p, *root;
2184 root = scst_proc_get_tgt_root(templ);
2186 /* create the proc file entry for the device */
2187 q2t_log_proc_data.data = (void *)templ->name;
2188 p = scst_create_proc_entry(root, Q2T_PROC_LOG_ENTRY_NAME,
2189 &q2t_log_proc_data);
2191 PRINT_ERROR("Not enough memory to register "
2192 "target driver %s entry %s in /proc",
2193 templ->name, Q2T_PROC_LOG_ENTRY_NAME);
2201 TRACE_EXIT_RES(res);
2206 static void q2t_proc_log_entry_clean(struct scst_tgt_template *templ)
2208 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
2209 struct proc_dir_entry *root;
2213 root = scst_proc_get_tgt_root(templ);
2215 remove_proc_entry(Q2T_PROC_LOG_ENTRY_NAME, root);
2223 static int __init q2t_init(void)
2229 q2t_cmd_cachep = KMEM_CACHE(q2t_cmd, SCST_SLAB_FLAGS);
2230 if (q2t_cmd_cachep == NULL) {
2235 res = scst_register_target_template(&tgt_template);
2240 * qla2xxx_tgt_register_driver() happens in q2t_target_detect
2241 * called via scst_register_target_template()
2244 res = q2t_proc_log_entry_build(&tgt_template);
2246 goto out_unreg_target;
2253 scst_unregister_target_template(&tgt_template);
2256 kmem_cache_destroy(q2t_cmd_cachep);
2258 qla2xxx_tgt_unregister_driver();
2262 static void __exit q2t_exit(void)
2266 q2t_proc_log_entry_clean(&tgt_template);
2268 scst_unregister_target_template(&tgt_template);
2270 qla2xxx_tgt_unregister_driver();
2272 kmem_cache_destroy(q2t_cmd_cachep);
2278 module_init(q2t_init);
2279 module_exit(q2t_exit);
2281 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar & Nathaniel Clark");
2282 MODULE_DESCRIPTION("Target mode logic for qla2xxx");
2283 MODULE_LICENSE("GPL");
2284 MODULE_VERSION(Q2T_VERSION_STRING);