cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tcm_qla2xxx.c (54177B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*******************************************************************************
      3 * This file contains tcm implementation using v4 configfs fabric infrastructure
      4 * for QLogic target mode HBAs
      5 *
      6 * (c) Copyright 2010-2013 Datera, Inc.
      7 *
      8 * Author: Nicholas A. Bellinger <nab@daterainc.com>
      9 *
     10 * tcm_qla2xxx_parse_wwn() and tcm_qla2xxx_format_wwn() contains code from
     11 * the TCM_FC / Open-FCoE.org fabric module.
     12 *
     13 * Copyright (c) 2010 Cisco Systems, Inc
     14 *
     15 ****************************************************************************/
     16
     17
     18#include <linux/module.h>
     19#include <linux/utsname.h>
     20#include <linux/vmalloc.h>
     21#include <linux/list.h>
     22#include <linux/slab.h>
     23#include <linux/types.h>
     24#include <linux/string.h>
     25#include <linux/configfs.h>
     26#include <linux/ctype.h>
     27#include <asm/unaligned.h>
     28#include <scsi/scsi_host.h>
     29#include <target/target_core_base.h>
     30#include <target/target_core_fabric.h>
     31
     32#include "qla_def.h"
     33#include "qla_target.h"
     34#include "tcm_qla2xxx.h"
     35
     36static struct workqueue_struct *tcm_qla2xxx_free_wq;
     37
     38/*
     39 * Parse WWN.
     40 * If strict, we require lower-case hex and colon separators to be sure
     41 * the name is the same as what would be generated by ft_format_wwn()
     42 * so the name and wwn are mapped one-to-one.
     43 */
     44static ssize_t tcm_qla2xxx_parse_wwn(const char *name, u64 *wwn, int strict)
     45{
     46	const char *cp;
     47	char c;
     48	u32 nibble;
     49	u32 byte = 0;
     50	u32 pos = 0;
     51	u32 err;
     52
     53	*wwn = 0;
     54	for (cp = name; cp < &name[TCM_QLA2XXX_NAMELEN - 1]; cp++) {
     55		c = *cp;
     56		if (c == '\n' && cp[1] == '\0')
     57			continue;
     58		if (strict && pos++ == 2 && byte++ < 7) {
     59			pos = 0;
     60			if (c == ':')
     61				continue;
     62			err = 1;
     63			goto fail;
     64		}
     65		if (c == '\0') {
     66			err = 2;
     67			if (strict && byte != 8)
     68				goto fail;
     69			return cp - name;
     70		}
     71		err = 3;
     72		if (isdigit(c))
     73			nibble = c - '0';
     74		else if (isxdigit(c) && (islower(c) || !strict))
     75			nibble = tolower(c) - 'a' + 10;
     76		else
     77			goto fail;
     78		*wwn = (*wwn << 4) | nibble;
     79	}
     80	err = 4;
     81fail:
     82	pr_debug("err %u len %zu pos %u byte %u\n",
     83			err, cp - name, pos, byte);
     84	return -1;
     85}
     86
     87static ssize_t tcm_qla2xxx_format_wwn(char *buf, size_t len, u64 wwn)
     88{
     89	u8 b[8];
     90
     91	put_unaligned_be64(wwn, b);
     92	return snprintf(buf, len,
     93		"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
     94		b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
     95}
     96
     97/*
     98 * From drivers/scsi/scsi_transport_fc.c:fc_parse_wwn
     99 */
    100static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm)
    101{
    102	unsigned int i, j;
    103	u8 wwn[8];
    104
    105	memset(wwn, 0, sizeof(wwn));
    106
    107	/* Validate and store the new name */
    108	for (i = 0, j = 0; i < 16; i++) {
    109		int value;
    110
    111		value = hex_to_bin(*ns++);
    112		if (value >= 0)
    113			j = (j << 4) | value;
    114		else
    115			return -EINVAL;
    116
    117		if (i % 2) {
    118			wwn[i/2] = j & 0xff;
    119			j = 0;
    120		}
    121	}
    122
    123	*nm = wwn_to_u64(wwn);
    124	return 0;
    125}
    126
    127/*
    128 * This parsing logic follows drivers/scsi/scsi_transport_fc.c:
    129 * store_fc_host_vport_create()
    130 */
    131static int tcm_qla2xxx_npiv_parse_wwn(
    132	const char *name,
    133	size_t count,
    134	u64 *wwpn,
    135	u64 *wwnn)
    136{
    137	unsigned int cnt = count;
    138	int rc;
    139
    140	*wwpn = 0;
    141	*wwnn = 0;
    142
    143	/* count may include a LF at end of string */
    144	if (name[cnt-1] == '\n' || name[cnt-1] == 0)
    145		cnt--;
    146
    147	/* validate we have enough characters for WWPN */
    148	if ((cnt != (16+1+16)) || (name[16] != ':'))
    149		return -EINVAL;
    150
    151	rc = tcm_qla2xxx_npiv_extract_wwn(&name[0], wwpn);
    152	if (rc != 0)
    153		return rc;
    154
    155	rc = tcm_qla2xxx_npiv_extract_wwn(&name[17], wwnn);
    156	if (rc != 0)
    157		return rc;
    158
    159	return 0;
    160}
    161
    162static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg)
    163{
    164	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    165				struct tcm_qla2xxx_tpg, se_tpg);
    166	struct tcm_qla2xxx_lport *lport = tpg->lport;
    167
    168	return lport->lport_naa_name;
    169}
    170
    171static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg)
    172{
    173	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    174				struct tcm_qla2xxx_tpg, se_tpg);
    175	return tpg->lport_tpgt;
    176}
    177
    178static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg)
    179{
    180	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    181				struct tcm_qla2xxx_tpg, se_tpg);
    182
    183	return tpg->tpg_attrib.generate_node_acls;
    184}
    185
    186static int tcm_qla2xxx_check_demo_mode_cache(struct se_portal_group *se_tpg)
    187{
    188	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    189				struct tcm_qla2xxx_tpg, se_tpg);
    190
    191	return tpg->tpg_attrib.cache_dynamic_acls;
    192}
    193
    194static int tcm_qla2xxx_check_demo_write_protect(struct se_portal_group *se_tpg)
    195{
    196	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    197				struct tcm_qla2xxx_tpg, se_tpg);
    198
    199	return tpg->tpg_attrib.demo_mode_write_protect;
    200}
    201
    202static int tcm_qla2xxx_check_prod_write_protect(struct se_portal_group *se_tpg)
    203{
    204	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    205				struct tcm_qla2xxx_tpg, se_tpg);
    206
    207	return tpg->tpg_attrib.prod_mode_write_protect;
    208}
    209
    210static int tcm_qla2xxx_check_demo_mode_login_only(struct se_portal_group *se_tpg)
    211{
    212	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    213				struct tcm_qla2xxx_tpg, se_tpg);
    214
    215	return tpg->tpg_attrib.demo_mode_login_only;
    216}
    217
    218static int tcm_qla2xxx_check_prot_fabric_only(struct se_portal_group *se_tpg)
    219{
    220	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    221				struct tcm_qla2xxx_tpg, se_tpg);
    222
    223	return tpg->tpg_attrib.fabric_prot_type;
    224}
    225
    226static u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg)
    227{
    228	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    229				struct tcm_qla2xxx_tpg, se_tpg);
    230
    231	return tpg->lport_tpgt;
    232}
    233
    234static void tcm_qla2xxx_complete_mcmd(struct work_struct *work)
    235{
    236	struct qla_tgt_mgmt_cmd *mcmd = container_of(work,
    237			struct qla_tgt_mgmt_cmd, free_work);
    238
    239	transport_generic_free_cmd(&mcmd->se_cmd, 0);
    240}
    241
    242/*
    243 * Called from qla_target_template->free_mcmd(), and will call
    244 * tcm_qla2xxx_release_cmd() via normal struct target_core_fabric_ops
    245 * release callback.  qla_hw_data->hardware_lock is expected to be held
    246 */
    247static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
    248{
    249	if (!mcmd)
    250		return;
    251	INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd);
    252	queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work);
    253}
    254
    255static void tcm_qla2xxx_complete_free(struct work_struct *work)
    256{
    257	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
    258	unsigned long flags;
    259
    260	cmd->cmd_in_wq = 0;
    261
    262	WARN_ON(cmd->trc_flags & TRC_CMD_FREE);
    263
    264	/* To do: protect all tgt_counters manipulations with proper locking. */
    265	cmd->qpair->tgt_counters.qla_core_ret_sta_ctio++;
    266	cmd->trc_flags |= TRC_CMD_FREE;
    267	cmd->cmd_sent_to_fw = 0;
    268
    269	spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
    270	list_del_init(&cmd->sess_cmd_list);
    271	spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
    272
    273	transport_generic_free_cmd(&cmd->se_cmd, 0);
    274}
    275
    276static struct qla_tgt_cmd *tcm_qla2xxx_get_cmd(struct fc_port *sess)
    277{
    278	struct se_session *se_sess = sess->se_sess;
    279	struct qla_tgt_cmd *cmd;
    280	int tag, cpu;
    281
    282	tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu);
    283	if (tag < 0)
    284		return NULL;
    285
    286	cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
    287	memset(cmd, 0, sizeof(struct qla_tgt_cmd));
    288	cmd->se_cmd.map_tag = tag;
    289	cmd->se_cmd.map_cpu = cpu;
    290
    291	return cmd;
    292}
    293
    294static void tcm_qla2xxx_rel_cmd(struct qla_tgt_cmd *cmd)
    295{
    296	target_free_tag(cmd->sess->se_sess, &cmd->se_cmd);
    297}
    298
    299/*
    300 * Called from qla_target_template->free_cmd(), and will call
    301 * tcm_qla2xxx_release_cmd via normal struct target_core_fabric_ops
    302 * release callback.  qla_hw_data->hardware_lock is expected to be held
    303 */
    304static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
    305{
    306	cmd->qpair->tgt_counters.core_qla_free_cmd++;
    307	cmd->cmd_in_wq = 1;
    308
    309	WARN_ON(cmd->trc_flags & TRC_CMD_DONE);
    310	cmd->trc_flags |= TRC_CMD_DONE;
    311
    312	INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
    313	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
    314}
    315
    316/*
    317 * Called from struct target_core_fabric_ops->check_stop_free() context
    318 */
    319static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
    320{
    321	struct qla_tgt_cmd *cmd;
    322
    323	if ((se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) == 0) {
    324		cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
    325		cmd->trc_flags |= TRC_CMD_CHK_STOP;
    326	}
    327
    328	return target_put_sess_cmd(se_cmd);
    329}
    330
    331/* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying
    332 * fabric descriptor @se_cmd command to release
    333 */
    334static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
    335{
    336	struct qla_tgt_cmd *cmd;
    337
    338	if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) {
    339		struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
    340				struct qla_tgt_mgmt_cmd, se_cmd);
    341		qlt_free_mcmd(mcmd);
    342		return;
    343	}
    344	cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
    345
    346	if (WARN_ON(cmd->cmd_sent_to_fw))
    347		return;
    348
    349	qlt_free_cmd(cmd);
    350}
    351
    352static void tcm_qla2xxx_release_session(struct kref *kref)
    353{
    354	struct fc_port  *sess = container_of(kref,
    355	    struct fc_port, sess_kref);
    356
    357	qlt_unreg_sess(sess);
    358}
    359
    360static void tcm_qla2xxx_put_sess(struct fc_port *sess)
    361{
    362	if (!sess)
    363		return;
    364
    365	kref_put(&sess->sess_kref, tcm_qla2xxx_release_session);
    366}
    367
    368static void tcm_qla2xxx_close_session(struct se_session *se_sess)
    369{
    370	struct fc_port *sess = se_sess->fabric_sess_ptr;
    371
    372	BUG_ON(!sess);
    373
    374	target_stop_session(se_sess);
    375
    376	sess->explicit_logout = 1;
    377	tcm_qla2xxx_put_sess(sess);
    378}
    379
    380static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
    381{
    382	return 0;
    383}
    384
    385static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
    386{
    387	struct qla_tgt_cmd *cmd = container_of(se_cmd,
    388				struct qla_tgt_cmd, se_cmd);
    389
    390	if (cmd->aborted) {
    391		/* Cmd can loop during Q-full.  tcm_qla2xxx_aborted_task
    392		 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
    393		 * already kick start the free.
    394		 */
    395		pr_debug("write_pending aborted cmd[%p] refcount %d "
    396			"transport_state %x, t_state %x, se_cmd_flags %x\n",
    397			cmd, kref_read(&cmd->se_cmd.cmd_kref),
    398			cmd->se_cmd.transport_state,
    399			cmd->se_cmd.t_state,
    400			cmd->se_cmd.se_cmd_flags);
    401		transport_generic_request_failure(&cmd->se_cmd,
    402			TCM_CHECK_CONDITION_ABORT_CMD);
    403		return 0;
    404	}
    405	cmd->trc_flags |= TRC_XFR_RDY;
    406	cmd->bufflen = se_cmd->data_length;
    407	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
    408
    409	cmd->sg_cnt = se_cmd->t_data_nents;
    410	cmd->sg = se_cmd->t_data_sg;
    411
    412	cmd->prot_sg_cnt = se_cmd->t_prot_nents;
    413	cmd->prot_sg = se_cmd->t_prot_sg;
    414	cmd->blk_sz  = se_cmd->se_dev->dev_attrib.block_size;
    415	se_cmd->pi_err = 0;
    416
    417	/*
    418	 * qla_target.c:qlt_rdy_to_xfer() will call dma_map_sg() to setup
    419	 * the SGL mappings into PCIe memory for incoming FCP WRITE data.
    420	 */
    421	return qlt_rdy_to_xfer(cmd);
    422}
    423
    424static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)
    425{
    426	return;
    427}
    428
    429static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd)
    430{
    431	if (!(se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
    432		struct qla_tgt_cmd *cmd = container_of(se_cmd,
    433				struct qla_tgt_cmd, se_cmd);
    434		return cmd->state;
    435	}
    436
    437	return 0;
    438}
    439
    440/*
    441 * Called from process context in qla_target.c:qlt_do_work() code
    442 */
    443static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
    444	unsigned char *cdb, uint32_t data_length, int fcp_task_attr,
    445	int data_dir, int bidi)
    446{
    447	struct se_cmd *se_cmd = &cmd->se_cmd;
    448	struct se_session *se_sess;
    449	struct fc_port *sess;
    450#ifdef CONFIG_TCM_QLA2XXX_DEBUG
    451	struct se_portal_group *se_tpg;
    452	struct tcm_qla2xxx_tpg *tpg;
    453#endif
    454	int rc, target_flags = TARGET_SCF_ACK_KREF;
    455	unsigned long flags;
    456
    457	if (bidi)
    458		target_flags |= TARGET_SCF_BIDI_OP;
    459
    460	if (se_cmd->cpuid != WORK_CPU_UNBOUND)
    461		target_flags |= TARGET_SCF_USE_CPUID;
    462
    463	sess = cmd->sess;
    464	if (!sess) {
    465		pr_err("Unable to locate struct fc_port from qla_tgt_cmd\n");
    466		return -EINVAL;
    467	}
    468
    469	se_sess = sess->se_sess;
    470	if (!se_sess) {
    471		pr_err("Unable to locate active struct se_session\n");
    472		return -EINVAL;
    473	}
    474
    475#ifdef CONFIG_TCM_QLA2XXX_DEBUG
    476	se_tpg = se_sess->se_tpg;
    477	tpg = container_of(se_tpg, struct tcm_qla2xxx_tpg, se_tpg);
    478	if (unlikely(tpg->tpg_attrib.jam_host)) {
    479		/* return, and dont run target_submit_cmd,discarding command */
    480		return 0;
    481	}
    482#endif
    483	cmd->qpair->tgt_counters.qla_core_sbt_cmd++;
    484
    485	spin_lock_irqsave(&sess->sess_cmd_lock, flags);
    486	list_add_tail(&cmd->sess_cmd_list, &sess->sess_cmd_list);
    487	spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
    488
    489	rc = target_init_cmd(se_cmd, se_sess, &cmd->sense_buffer[0],
    490			     cmd->unpacked_lun, data_length, fcp_task_attr,
    491			     data_dir, target_flags);
    492	if (rc)
    493		return rc;
    494
    495	if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0,
    496			       GFP_KERNEL))
    497		return 0;
    498
    499	target_submit(se_cmd);
    500	return 0;
    501}
    502
    503static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
    504{
    505	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
    506
    507	/*
    508	 * Ensure that the complete FCP WRITE payload has been received.
    509	 * Otherwise return an exception via CHECK_CONDITION status.
    510	 */
    511	cmd->cmd_in_wq = 0;
    512	cmd->cmd_sent_to_fw = 0;
    513	if (cmd->aborted) {
    514		transport_generic_request_failure(&cmd->se_cmd,
    515			TCM_CHECK_CONDITION_ABORT_CMD);
    516		return;
    517	}
    518
    519	cmd->qpair->tgt_counters.qla_core_ret_ctio++;
    520	if (!cmd->write_data_transferred) {
    521		switch (cmd->dif_err_code) {
    522		case DIF_ERR_GRD:
    523			cmd->se_cmd.pi_err =
    524			    TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
    525			break;
    526		case DIF_ERR_REF:
    527			cmd->se_cmd.pi_err =
    528			    TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
    529			break;
    530		case DIF_ERR_APP:
    531			cmd->se_cmd.pi_err =
    532			    TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
    533			break;
    534		case DIF_ERR_NONE:
    535		default:
    536			break;
    537		}
    538
    539		if (cmd->se_cmd.pi_err)
    540			transport_generic_request_failure(&cmd->se_cmd,
    541				cmd->se_cmd.pi_err);
    542		else
    543			transport_generic_request_failure(&cmd->se_cmd,
    544				TCM_CHECK_CONDITION_ABORT_CMD);
    545
    546		return;
    547	}
    548
    549	return target_execute_cmd(&cmd->se_cmd);
    550}
    551
    552/*
    553 * Called from qla_target.c:qlt_do_ctio_completion()
    554 */
    555static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
    556{
    557	cmd->trc_flags |= TRC_DATA_IN;
    558	cmd->cmd_in_wq = 1;
    559	INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
    560	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
    561}
    562
    563static int tcm_qla2xxx_chk_dif_tags(uint32_t tag)
    564{
    565	return 0;
    566}
    567
    568static int tcm_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd,
    569    uint16_t *pfw_prot_opts)
    570{
    571	struct se_cmd *se_cmd = &cmd->se_cmd;
    572
    573	if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_GUARD))
    574		*pfw_prot_opts |= PO_DISABLE_GUARD_CHECK;
    575
    576	if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_APPTAG))
    577		*pfw_prot_opts |= PO_DIS_APP_TAG_VALD;
    578
    579	return 0;
    580}
    581
    582/*
    583 * Called from qla_target.c:qlt_issue_task_mgmt()
    584 */
    585static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
    586	uint16_t tmr_func, uint32_t tag)
    587{
    588	struct fc_port *sess = mcmd->sess;
    589	struct se_cmd *se_cmd = &mcmd->se_cmd;
    590	int transl_tmr_func = 0;
    591
    592	switch (tmr_func) {
    593	case QLA_TGT_ABTS:
    594		pr_debug("%ld: ABTS received\n", sess->vha->host_no);
    595		transl_tmr_func = TMR_ABORT_TASK;
    596		break;
    597	case QLA_TGT_2G_ABORT_TASK:
    598		pr_debug("%ld: 2G Abort Task received\n", sess->vha->host_no);
    599		transl_tmr_func = TMR_ABORT_TASK;
    600		break;
    601	case QLA_TGT_CLEAR_ACA:
    602		pr_debug("%ld: CLEAR_ACA received\n", sess->vha->host_no);
    603		transl_tmr_func = TMR_CLEAR_ACA;
    604		break;
    605	case QLA_TGT_TARGET_RESET:
    606		pr_debug("%ld: TARGET_RESET received\n", sess->vha->host_no);
    607		transl_tmr_func = TMR_TARGET_WARM_RESET;
    608		break;
    609	case QLA_TGT_LUN_RESET:
    610		pr_debug("%ld: LUN_RESET received\n", sess->vha->host_no);
    611		transl_tmr_func = TMR_LUN_RESET;
    612		break;
    613	case QLA_TGT_CLEAR_TS:
    614		pr_debug("%ld: CLEAR_TS received\n", sess->vha->host_no);
    615		transl_tmr_func = TMR_CLEAR_TASK_SET;
    616		break;
    617	case QLA_TGT_ABORT_TS:
    618		pr_debug("%ld: ABORT_TS received\n", sess->vha->host_no);
    619		transl_tmr_func = TMR_ABORT_TASK_SET;
    620		break;
    621	default:
    622		pr_debug("%ld: Unknown task mgmt fn 0x%x\n",
    623		    sess->vha->host_no, tmr_func);
    624		return -ENOSYS;
    625	}
    626
    627	return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd,
    628	    transl_tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF);
    629}
    630
    631static struct qla_tgt_cmd *tcm_qla2xxx_find_cmd_by_tag(struct fc_port *sess,
    632    uint64_t tag)
    633{
    634	struct qla_tgt_cmd *cmd;
    635	unsigned long flags;
    636
    637	if (!sess->se_sess)
    638		return NULL;
    639
    640	spin_lock_irqsave(&sess->sess_cmd_lock, flags);
    641	list_for_each_entry(cmd, &sess->sess_cmd_list, sess_cmd_list) {
    642		if (cmd->se_cmd.tag == tag)
    643			goto done;
    644	}
    645	cmd = NULL;
    646done:
    647	spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
    648
    649	return cmd;
    650}
    651
    652static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
    653{
    654	struct qla_tgt_cmd *cmd = container_of(se_cmd,
    655				struct qla_tgt_cmd, se_cmd);
    656
    657	if (cmd->aborted) {
    658		/* Cmd can loop during Q-full.  tcm_qla2xxx_aborted_task
    659		 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
    660		 * already kick start the free.
    661		 */
    662		pr_debug("queue_data_in aborted cmd[%p] refcount %d "
    663			"transport_state %x, t_state %x, se_cmd_flags %x\n",
    664			cmd, kref_read(&cmd->se_cmd.cmd_kref),
    665			cmd->se_cmd.transport_state,
    666			cmd->se_cmd.t_state,
    667			cmd->se_cmd.se_cmd_flags);
    668		return 0;
    669	}
    670
    671	cmd->trc_flags |= TRC_XMIT_DATA;
    672	cmd->bufflen = se_cmd->data_length;
    673	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
    674
    675	cmd->sg_cnt = se_cmd->t_data_nents;
    676	cmd->sg = se_cmd->t_data_sg;
    677	cmd->offset = 0;
    678
    679	cmd->prot_sg_cnt = se_cmd->t_prot_nents;
    680	cmd->prot_sg = se_cmd->t_prot_sg;
    681	cmd->blk_sz  = se_cmd->se_dev->dev_attrib.block_size;
    682	se_cmd->pi_err = 0;
    683
    684	/*
    685	 * Now queue completed DATA_IN the qla2xxx LLD and response ring
    686	 */
    687	return qlt_xmit_response(cmd, QLA_TGT_XMIT_DATA|QLA_TGT_XMIT_STATUS,
    688				se_cmd->scsi_status);
    689}
    690
    691static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
    692{
    693	struct qla_tgt_cmd *cmd = container_of(se_cmd,
    694				struct qla_tgt_cmd, se_cmd);
    695	int xmit_type = QLA_TGT_XMIT_STATUS;
    696
    697	if (cmd->aborted) {
    698		/*
    699		 * Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
    700		 * can get ahead of this cmd. tcm_qla2xxx_aborted_task
    701		 * already kick start the free.
    702		 */
    703		pr_debug(
    704		    "queue_data_in aborted cmd[%p] refcount %d transport_state %x, t_state %x, se_cmd_flags %x\n",
    705		    cmd, kref_read(&cmd->se_cmd.cmd_kref),
    706		    cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
    707		    cmd->se_cmd.se_cmd_flags);
    708		return 0;
    709	}
    710	cmd->bufflen = se_cmd->data_length;
    711	cmd->sg = NULL;
    712	cmd->sg_cnt = 0;
    713	cmd->offset = 0;
    714	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
    715	cmd->trc_flags |= TRC_XMIT_STATUS;
    716
    717	if (se_cmd->data_direction == DMA_FROM_DEVICE) {
    718		/*
    719		 * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen
    720		 * for qla_tgt_xmit_response LLD code
    721		 */
    722		if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
    723			se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT;
    724			se_cmd->residual_count = 0;
    725		}
    726		se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
    727		se_cmd->residual_count += se_cmd->data_length;
    728
    729		cmd->bufflen = 0;
    730	}
    731	/*
    732	 * Now queue status response to qla2xxx LLD code and response ring
    733	 */
    734	return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status);
    735}
    736
    737static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
    738{
    739	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
    740	struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
    741				struct qla_tgt_mgmt_cmd, se_cmd);
    742
    743	pr_debug("queue_tm_rsp: mcmd: %p func: 0x%02x response: 0x%02x\n",
    744			mcmd, se_tmr->function, se_tmr->response);
    745	/*
    746	 * Do translation between TCM TM response codes and
    747	 * QLA2xxx FC TM response codes.
    748	 */
    749	switch (se_tmr->response) {
    750	case TMR_FUNCTION_COMPLETE:
    751		mcmd->fc_tm_rsp = FC_TM_SUCCESS;
    752		break;
    753	case TMR_TASK_DOES_NOT_EXIST:
    754		mcmd->fc_tm_rsp = FC_TM_BAD_CMD;
    755		break;
    756	case TMR_FUNCTION_REJECTED:
    757		mcmd->fc_tm_rsp = FC_TM_REJECT;
    758		break;
    759	case TMR_LUN_DOES_NOT_EXIST:
    760	default:
    761		mcmd->fc_tm_rsp = FC_TM_FAILED;
    762		break;
    763	}
    764	/*
    765	 * Queue the TM response to QLA2xxx LLD to build a
    766	 * CTIO response packet.
    767	 */
    768	qlt_xmit_tm_rsp(mcmd);
    769}
    770
    771static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
    772{
    773	struct qla_tgt_cmd *cmd;
    774	unsigned long flags;
    775
    776	if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
    777		return;
    778
    779	cmd  = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
    780
    781	spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
    782	list_del_init(&cmd->sess_cmd_list);
    783	spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
    784
    785	qlt_abort_cmd(cmd);
    786}
    787
    788static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
    789			struct tcm_qla2xxx_nacl *, struct fc_port *);
    790/*
    791 * Expected to be called with struct qla_hw_data->tgt.sess_lock held
    792 */
    793static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct fc_port *sess)
    794{
    795	struct se_node_acl *se_nacl = sess->se_sess->se_node_acl;
    796	struct se_portal_group *se_tpg = se_nacl->se_tpg;
    797	struct se_wwn *se_wwn = se_tpg->se_tpg_wwn;
    798	struct tcm_qla2xxx_lport *lport = container_of(se_wwn,
    799				struct tcm_qla2xxx_lport, lport_wwn);
    800	struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
    801				struct tcm_qla2xxx_nacl, se_node_acl);
    802	void *node;
    803
    804	pr_debug("fc_rport domain: port_id 0x%06x\n", nacl->nport_id);
    805
    806	node = btree_remove32(&lport->lport_fcport_map, nacl->nport_id);
    807	if (WARN_ON(node && (node != se_nacl))) {
    808		/*
    809		 * The nacl no longer matches what we think it should be.
    810		 * Most likely a new dynamic acl has been added while
    811		 * someone dropped the hardware lock.  It clearly is a
    812		 * bug elsewhere, but this bit can't make things worse.
    813		 */
    814		btree_insert32(&lport->lport_fcport_map, nacl->nport_id,
    815			       node, GFP_ATOMIC);
    816	}
    817
    818	pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n",
    819	    se_nacl, nacl->nport_wwnn, nacl->nport_id);
    820	/*
    821	 * Now clear the se_nacl and session pointers from our HW lport lookup
    822	 * table mapping for this initiator's fabric S_ID and LOOP_ID entries.
    823	 *
    824	 * This is done ahead of callbacks into tcm_qla2xxx_free_session() ->
    825	 * target_wait_for_sess_cmds() before the session waits for outstanding
    826	 * I/O to complete, to avoid a race between session shutdown execution
    827	 * and incoming ATIOs or TMRs picking up a stale se_node_act reference.
    828	 */
    829	tcm_qla2xxx_clear_sess_lookup(lport, nacl, sess);
    830}
    831
    832static void tcm_qla2xxx_shutdown_sess(struct fc_port *sess)
    833{
    834	target_stop_session(sess->se_sess);
    835}
    836
    837static int tcm_qla2xxx_init_nodeacl(struct se_node_acl *se_nacl,
    838		const char *name)
    839{
    840	struct tcm_qla2xxx_nacl *nacl =
    841		container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
    842	u64 wwnn;
    843
    844	if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0)
    845		return -EINVAL;
    846
    847	nacl->nport_wwnn = wwnn;
    848	tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn);
    849
    850	return 0;
    851}
    852
    853/* Start items for tcm_qla2xxx_tpg_attrib_cit */
    854
    855#define DEF_QLA_TPG_ATTRIB(name)					\
    856									\
    857static ssize_t tcm_qla2xxx_tpg_attrib_##name##_show(			\
    858		struct config_item *item, char *page)			\
    859{									\
    860	struct se_portal_group *se_tpg = attrib_to_tpg(item);		\
    861	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,		\
    862			struct tcm_qla2xxx_tpg, se_tpg);		\
    863									\
    864	return sprintf(page, "%d\n", tpg->tpg_attrib.name);	\
    865}									\
    866									\
    867static ssize_t tcm_qla2xxx_tpg_attrib_##name##_store(			\
    868		struct config_item *item, const char *page, size_t count) \
    869{									\
    870	struct se_portal_group *se_tpg = attrib_to_tpg(item);		\
    871	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,		\
    872			struct tcm_qla2xxx_tpg, se_tpg);		\
    873	struct tcm_qla2xxx_tpg_attrib *a = &tpg->tpg_attrib;		\
    874	unsigned long val;						\
    875	int ret;							\
    876									\
    877	ret = kstrtoul(page, 0, &val);					\
    878	if (ret < 0) {							\
    879		pr_err("kstrtoul() failed with"				\
    880				" ret: %d\n", ret);			\
    881		return -EINVAL;						\
    882	}								\
    883									\
    884	if ((val != 0) && (val != 1)) {					\
    885		pr_err("Illegal boolean value %lu\n", val);		\
    886		return -EINVAL;						\
    887	}								\
    888									\
    889	a->name = val;							\
    890									\
    891	return count;							\
    892}									\
    893CONFIGFS_ATTR(tcm_qla2xxx_tpg_attrib_, name)
    894
    895DEF_QLA_TPG_ATTRIB(generate_node_acls);
    896DEF_QLA_TPG_ATTRIB(cache_dynamic_acls);
    897DEF_QLA_TPG_ATTRIB(demo_mode_write_protect);
    898DEF_QLA_TPG_ATTRIB(prod_mode_write_protect);
    899DEF_QLA_TPG_ATTRIB(demo_mode_login_only);
    900#ifdef CONFIG_TCM_QLA2XXX_DEBUG
    901DEF_QLA_TPG_ATTRIB(jam_host);
    902#endif
    903
    904static struct configfs_attribute *tcm_qla2xxx_tpg_attrib_attrs[] = {
    905	&tcm_qla2xxx_tpg_attrib_attr_generate_node_acls,
    906	&tcm_qla2xxx_tpg_attrib_attr_cache_dynamic_acls,
    907	&tcm_qla2xxx_tpg_attrib_attr_demo_mode_write_protect,
    908	&tcm_qla2xxx_tpg_attrib_attr_prod_mode_write_protect,
    909	&tcm_qla2xxx_tpg_attrib_attr_demo_mode_login_only,
    910#ifdef CONFIG_TCM_QLA2XXX_DEBUG
    911	&tcm_qla2xxx_tpg_attrib_attr_jam_host,
    912#endif
    913	NULL,
    914};
    915
    916/* End items for tcm_qla2xxx_tpg_attrib_cit */
    917
    918static int tcm_qla2xxx_enable_tpg(struct se_portal_group *se_tpg,
    919				  bool enable)
    920{
    921	struct se_wwn *se_wwn = se_tpg->se_tpg_wwn;
    922	struct tcm_qla2xxx_lport *lport = container_of(se_wwn,
    923			struct tcm_qla2xxx_lport, lport_wwn);
    924	struct scsi_qla_host *vha = lport->qla_vha;
    925	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    926			struct tcm_qla2xxx_tpg, se_tpg);
    927
    928	if (enable) {
    929		if (atomic_read(&tpg->lport_tpg_enabled))
    930			return -EEXIST;
    931
    932		atomic_set(&tpg->lport_tpg_enabled, 1);
    933		qlt_enable_vha(vha);
    934	} else {
    935		if (!atomic_read(&tpg->lport_tpg_enabled))
    936			return 0;
    937
    938		atomic_set(&tpg->lport_tpg_enabled, 0);
    939		qlt_stop_phase1(vha->vha_tgt.qla_tgt);
    940		qlt_stop_phase2(vha->vha_tgt.qla_tgt);
    941	}
    942
    943	return 0;
    944}
    945
    946static ssize_t tcm_qla2xxx_tpg_dynamic_sessions_show(struct config_item *item,
    947		char *page)
    948{
    949	return target_show_dynamic_sessions(to_tpg(item), page);
    950}
    951
    952static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_store(struct config_item *item,
    953		const char *page, size_t count)
    954{
    955	struct se_portal_group *se_tpg = to_tpg(item);
    956	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    957				struct tcm_qla2xxx_tpg, se_tpg);
    958	unsigned long val;
    959	int ret = kstrtoul(page, 0, &val);
    960
    961	if (ret) {
    962		pr_err("kstrtoul() returned %d for fabric_prot_type\n", ret);
    963		return ret;
    964	}
    965	if (val != 0 && val != 1 && val != 3) {
    966		pr_err("Invalid qla2xxx fabric_prot_type: %lu\n", val);
    967		return -EINVAL;
    968	}
    969	tpg->tpg_attrib.fabric_prot_type = val;
    970
    971	return count;
    972}
    973
    974static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item,
    975		char *page)
    976{
    977	struct se_portal_group *se_tpg = to_tpg(item);
    978	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
    979				struct tcm_qla2xxx_tpg, se_tpg);
    980
    981	return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type);
    982}
    983
    984CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions);
    985CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type);
    986
    987static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = {
    988	&tcm_qla2xxx_tpg_attr_dynamic_sessions,
    989	&tcm_qla2xxx_tpg_attr_fabric_prot_type,
    990	NULL,
    991};
    992
    993static struct se_portal_group *tcm_qla2xxx_make_tpg(struct se_wwn *wwn,
    994						    const char *name)
    995{
    996	struct tcm_qla2xxx_lport *lport = container_of(wwn,
    997			struct tcm_qla2xxx_lport, lport_wwn);
    998	struct tcm_qla2xxx_tpg *tpg;
    999	unsigned long tpgt;
   1000	int ret;
   1001
   1002	if (strstr(name, "tpgt_") != name)
   1003		return ERR_PTR(-EINVAL);
   1004	if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX)
   1005		return ERR_PTR(-EINVAL);
   1006
   1007	if ((tpgt != 1)) {
   1008		pr_err("In non NPIV mode, a single TPG=1 is used for HW port mappings\n");
   1009		return ERR_PTR(-ENOSYS);
   1010	}
   1011
   1012	tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL);
   1013	if (!tpg) {
   1014		pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n");
   1015		return ERR_PTR(-ENOMEM);
   1016	}
   1017	tpg->lport = lport;
   1018	tpg->lport_tpgt = tpgt;
   1019	/*
   1020	 * By default allow READ-ONLY TPG demo-mode access w/ cached dynamic
   1021	 * NodeACLs
   1022	 */
   1023	tpg->tpg_attrib.generate_node_acls = 1;
   1024	tpg->tpg_attrib.demo_mode_write_protect = 1;
   1025	tpg->tpg_attrib.cache_dynamic_acls = 1;
   1026	tpg->tpg_attrib.demo_mode_login_only = 1;
   1027	tpg->tpg_attrib.jam_host = 0;
   1028
   1029	ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);
   1030	if (ret < 0) {
   1031		kfree(tpg);
   1032		return NULL;
   1033	}
   1034
   1035	lport->tpg_1 = tpg;
   1036
   1037	return &tpg->se_tpg;
   1038}
   1039
   1040static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg)
   1041{
   1042	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
   1043			struct tcm_qla2xxx_tpg, se_tpg);
   1044	struct tcm_qla2xxx_lport *lport = tpg->lport;
   1045	struct scsi_qla_host *vha = lport->qla_vha;
   1046	/*
   1047	 * Call into qla2x_target.c LLD logic to shutdown the active
   1048	 * FC Nexuses and disable target mode operation for this qla_hw_data
   1049	 */
   1050	if (vha->vha_tgt.qla_tgt && !vha->vha_tgt.qla_tgt->tgt_stop)
   1051		qlt_stop_phase1(vha->vha_tgt.qla_tgt);
   1052
   1053	core_tpg_deregister(se_tpg);
   1054	/*
   1055	 * Clear local TPG=1 pointer for non NPIV mode.
   1056	 */
   1057	lport->tpg_1 = NULL;
   1058	kfree(tpg);
   1059}
   1060
   1061static int tcm_qla2xxx_npiv_enable_tpg(struct se_portal_group *se_tpg,
   1062				    bool enable)
   1063{
   1064	struct se_wwn *se_wwn = se_tpg->se_tpg_wwn;
   1065	struct tcm_qla2xxx_lport *lport = container_of(se_wwn,
   1066			struct tcm_qla2xxx_lport, lport_wwn);
   1067	struct scsi_qla_host *vha = lport->qla_vha;
   1068	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
   1069			struct tcm_qla2xxx_tpg, se_tpg);
   1070
   1071	if (enable) {
   1072		if (atomic_read(&tpg->lport_tpg_enabled))
   1073			return -EEXIST;
   1074
   1075		atomic_set(&tpg->lport_tpg_enabled, 1);
   1076		qlt_enable_vha(vha);
   1077	} else {
   1078		if (!atomic_read(&tpg->lport_tpg_enabled))
   1079			return 0;
   1080
   1081		atomic_set(&tpg->lport_tpg_enabled, 0);
   1082		qlt_stop_phase1(vha->vha_tgt.qla_tgt);
   1083		qlt_stop_phase2(vha->vha_tgt.qla_tgt);
   1084	}
   1085
   1086	return 0;
   1087}
   1088
   1089static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(struct se_wwn *wwn,
   1090							 const char *name)
   1091{
   1092	struct tcm_qla2xxx_lport *lport = container_of(wwn,
   1093			struct tcm_qla2xxx_lport, lport_wwn);
   1094	struct tcm_qla2xxx_tpg *tpg;
   1095	unsigned long tpgt;
   1096	int ret;
   1097
   1098	if (strstr(name, "tpgt_") != name)
   1099		return ERR_PTR(-EINVAL);
   1100	if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX)
   1101		return ERR_PTR(-EINVAL);
   1102
   1103	tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL);
   1104	if (!tpg) {
   1105		pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n");
   1106		return ERR_PTR(-ENOMEM);
   1107	}
   1108	tpg->lport = lport;
   1109	tpg->lport_tpgt = tpgt;
   1110
   1111	/*
   1112	 * By default allow READ-ONLY TPG demo-mode access w/ cached dynamic
   1113	 * NodeACLs
   1114	 */
   1115	tpg->tpg_attrib.generate_node_acls = 1;
   1116	tpg->tpg_attrib.demo_mode_write_protect = 1;
   1117	tpg->tpg_attrib.cache_dynamic_acls = 1;
   1118	tpg->tpg_attrib.demo_mode_login_only = 1;
   1119
   1120	ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);
   1121	if (ret < 0) {
   1122		kfree(tpg);
   1123		return NULL;
   1124	}
   1125	lport->tpg_1 = tpg;
   1126	return &tpg->se_tpg;
   1127}
   1128
   1129/*
   1130 * Expected to be called with struct qla_hw_data->tgt.sess_lock held
   1131 */
   1132static struct fc_port *tcm_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha,
   1133						     const be_id_t s_id)
   1134{
   1135	struct tcm_qla2xxx_lport *lport;
   1136	struct se_node_acl *se_nacl;
   1137	struct tcm_qla2xxx_nacl *nacl;
   1138	u32 key;
   1139
   1140	lport = vha->vha_tgt.target_lport_ptr;
   1141	if (!lport) {
   1142		pr_err("Unable to locate struct tcm_qla2xxx_lport\n");
   1143		dump_stack();
   1144		return NULL;
   1145	}
   1146
   1147	key = sid_to_key(s_id);
   1148	pr_debug("find_sess_by_s_id: 0x%06x\n", key);
   1149
   1150	se_nacl = btree_lookup32(&lport->lport_fcport_map, key);
   1151	if (!se_nacl) {
   1152		pr_debug("Unable to locate s_id: 0x%06x\n", key);
   1153		return NULL;
   1154	}
   1155	pr_debug("find_sess_by_s_id: located se_nacl: %p, initiatorname: %s\n",
   1156	    se_nacl, se_nacl->initiatorname);
   1157
   1158	nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
   1159	if (!nacl->fc_port) {
   1160		pr_err("Unable to locate struct fc_port\n");
   1161		return NULL;
   1162	}
   1163
   1164	return nacl->fc_port;
   1165}
   1166
   1167/*
   1168 * Expected to be called with struct qla_hw_data->tgt.sess_lock held
   1169 */
   1170static void tcm_qla2xxx_set_sess_by_s_id(
   1171	struct tcm_qla2xxx_lport *lport,
   1172	struct se_node_acl *new_se_nacl,
   1173	struct tcm_qla2xxx_nacl *nacl,
   1174	struct se_session *se_sess,
   1175	struct fc_port *fc_port,
   1176	be_id_t s_id)
   1177{
   1178	u32 key;
   1179	void *slot;
   1180	int rc;
   1181
   1182	key = sid_to_key(s_id);
   1183	pr_debug("set_sess_by_s_id: %06x\n", key);
   1184
   1185	slot = btree_lookup32(&lport->lport_fcport_map, key);
   1186	if (!slot) {
   1187		if (new_se_nacl) {
   1188			pr_debug("Setting up new fc_port entry to new_se_nacl\n");
   1189			nacl->nport_id = key;
   1190			rc = btree_insert32(&lport->lport_fcport_map, key,
   1191					new_se_nacl, GFP_ATOMIC);
   1192			if (rc)
   1193				printk(KERN_ERR "Unable to insert s_id into fcport_map: %06x\n",
   1194				    (int)key);
   1195		} else {
   1196			pr_debug("Wiping nonexisting fc_port entry\n");
   1197		}
   1198
   1199		fc_port->se_sess = se_sess;
   1200		nacl->fc_port = fc_port;
   1201		return;
   1202	}
   1203
   1204	if (nacl->fc_port) {
   1205		if (new_se_nacl == NULL) {
   1206			pr_debug("Clearing existing nacl->fc_port and fc_port entry\n");
   1207			btree_remove32(&lport->lport_fcport_map, key);
   1208			nacl->fc_port = NULL;
   1209			return;
   1210		}
   1211		pr_debug("Replacing existing nacl->fc_port and fc_port entry\n");
   1212		btree_update32(&lport->lport_fcport_map, key, new_se_nacl);
   1213		fc_port->se_sess = se_sess;
   1214		nacl->fc_port = fc_port;
   1215		return;
   1216	}
   1217
   1218	if (new_se_nacl == NULL) {
   1219		pr_debug("Clearing existing fc_port entry\n");
   1220		btree_remove32(&lport->lport_fcport_map, key);
   1221		return;
   1222	}
   1223
   1224	pr_debug("Replacing existing fc_port entry w/o active nacl->fc_port\n");
   1225	btree_update32(&lport->lport_fcport_map, key, new_se_nacl);
   1226	fc_port->se_sess = se_sess;
   1227	nacl->fc_port = fc_port;
   1228
   1229	pr_debug("Setup nacl->fc_port %p by s_id for se_nacl: %p, initiatorname: %s\n",
   1230	    nacl->fc_port, new_se_nacl, new_se_nacl->initiatorname);
   1231}
   1232
   1233/*
   1234 * Expected to be called with struct qla_hw_data->tgt.sess_lock held
   1235 */
   1236static struct fc_port *tcm_qla2xxx_find_sess_by_loop_id(
   1237	scsi_qla_host_t *vha,
   1238	const uint16_t loop_id)
   1239{
   1240	struct tcm_qla2xxx_lport *lport;
   1241	struct se_node_acl *se_nacl;
   1242	struct tcm_qla2xxx_nacl *nacl;
   1243	struct tcm_qla2xxx_fc_loopid *fc_loopid;
   1244
   1245	lport = vha->vha_tgt.target_lport_ptr;
   1246	if (!lport) {
   1247		pr_err("Unable to locate struct tcm_qla2xxx_lport\n");
   1248		dump_stack();
   1249		return NULL;
   1250	}
   1251
   1252	pr_debug("find_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id);
   1253
   1254	fc_loopid = lport->lport_loopid_map + loop_id;
   1255	se_nacl = fc_loopid->se_nacl;
   1256	if (!se_nacl) {
   1257		pr_debug("Unable to locate se_nacl by loop_id: 0x%04x\n",
   1258		    loop_id);
   1259		return NULL;
   1260	}
   1261
   1262	nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
   1263
   1264	if (!nacl->fc_port) {
   1265		pr_err("Unable to locate struct fc_port\n");
   1266		return NULL;
   1267	}
   1268
   1269	return nacl->fc_port;
   1270}
   1271
   1272/*
   1273 * Expected to be called with struct qla_hw_data->tgt.sess_lock held
   1274 */
   1275static void tcm_qla2xxx_set_sess_by_loop_id(
   1276	struct tcm_qla2xxx_lport *lport,
   1277	struct se_node_acl *new_se_nacl,
   1278	struct tcm_qla2xxx_nacl *nacl,
   1279	struct se_session *se_sess,
   1280	struct fc_port *fc_port,
   1281	uint16_t loop_id)
   1282{
   1283	struct se_node_acl *saved_nacl;
   1284	struct tcm_qla2xxx_fc_loopid *fc_loopid;
   1285
   1286	pr_debug("set_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id);
   1287
   1288	fc_loopid = &((struct tcm_qla2xxx_fc_loopid *)
   1289			lport->lport_loopid_map)[loop_id];
   1290
   1291	saved_nacl = fc_loopid->se_nacl;
   1292	if (!saved_nacl) {
   1293		pr_debug("Setting up new fc_loopid->se_nacl to new_se_nacl\n");
   1294		fc_loopid->se_nacl = new_se_nacl;
   1295		if (fc_port->se_sess != se_sess)
   1296			fc_port->se_sess = se_sess;
   1297		if (nacl->fc_port != fc_port)
   1298			nacl->fc_port = fc_port;
   1299		return;
   1300	}
   1301
   1302	if (nacl->fc_port) {
   1303		if (new_se_nacl == NULL) {
   1304			pr_debug("Clearing nacl->fc_port and fc_loopid->se_nacl\n");
   1305			fc_loopid->se_nacl = NULL;
   1306			nacl->fc_port = NULL;
   1307			return;
   1308		}
   1309
   1310		pr_debug("Replacing existing nacl->fc_port and fc_loopid->se_nacl\n");
   1311		fc_loopid->se_nacl = new_se_nacl;
   1312		if (fc_port->se_sess != se_sess)
   1313			fc_port->se_sess = se_sess;
   1314		if (nacl->fc_port != fc_port)
   1315			nacl->fc_port = fc_port;
   1316		return;
   1317	}
   1318
   1319	if (new_se_nacl == NULL) {
   1320		pr_debug("Clearing fc_loopid->se_nacl\n");
   1321		fc_loopid->se_nacl = NULL;
   1322		return;
   1323	}
   1324
   1325	pr_debug("Replacing existing fc_loopid->se_nacl w/o active nacl->fc_port\n");
   1326	fc_loopid->se_nacl = new_se_nacl;
   1327	if (fc_port->se_sess != se_sess)
   1328		fc_port->se_sess = se_sess;
   1329	if (nacl->fc_port != fc_port)
   1330		nacl->fc_port = fc_port;
   1331
   1332	pr_debug("Setup nacl->fc_port %p by loop_id for se_nacl: %p, initiatorname: %s\n",
   1333	    nacl->fc_port, new_se_nacl, new_se_nacl->initiatorname);
   1334}
   1335
   1336/*
   1337 * Should always be called with qla_hw_data->tgt.sess_lock held.
   1338 */
   1339static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *lport,
   1340		struct tcm_qla2xxx_nacl *nacl, struct fc_port *sess)
   1341{
   1342	struct se_session *se_sess = sess->se_sess;
   1343
   1344	tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess,
   1345				     sess, port_id_to_be_id(sess->d_id));
   1346	tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess,
   1347				sess, sess->loop_id);
   1348}
   1349
   1350static void tcm_qla2xxx_free_session(struct fc_port *sess)
   1351{
   1352	struct qla_tgt *tgt = sess->tgt;
   1353	struct qla_hw_data *ha = tgt->ha;
   1354	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
   1355	struct se_session *se_sess;
   1356	struct tcm_qla2xxx_lport *lport;
   1357
   1358	se_sess = sess->se_sess;
   1359	if (!se_sess) {
   1360		pr_err("struct fc_port->se_sess is NULL\n");
   1361		dump_stack();
   1362		return;
   1363	}
   1364
   1365	lport = vha->vha_tgt.target_lport_ptr;
   1366	if (!lport) {
   1367		pr_err("Unable to locate struct tcm_qla2xxx_lport\n");
   1368		dump_stack();
   1369		return;
   1370	}
   1371	target_wait_for_sess_cmds(se_sess);
   1372
   1373	target_remove_session(se_sess);
   1374}
   1375
   1376static int tcm_qla2xxx_session_cb(struct se_portal_group *se_tpg,
   1377				  struct se_session *se_sess, void *p)
   1378{
   1379	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
   1380				struct tcm_qla2xxx_tpg, se_tpg);
   1381	struct tcm_qla2xxx_lport *lport = tpg->lport;
   1382	struct qla_hw_data *ha = lport->qla_vha->hw;
   1383	struct se_node_acl *se_nacl = se_sess->se_node_acl;
   1384	struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
   1385				struct tcm_qla2xxx_nacl, se_node_acl);
   1386	struct fc_port *qlat_sess = p;
   1387	uint16_t loop_id = qlat_sess->loop_id;
   1388	unsigned long flags;
   1389
   1390	/*
   1391	 * And now setup se_nacl and session pointers into HW lport internal
   1392	 * mappings for fabric S_ID and LOOP_ID.
   1393	 */
   1394	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
   1395	tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess, qlat_sess,
   1396				     port_id_to_be_id(qlat_sess->d_id));
   1397	tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl,
   1398					se_sess, qlat_sess, loop_id);
   1399	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
   1400
   1401	return 0;
   1402}
   1403
   1404/*
   1405 * Called via qlt_create_sess():ha->qla2x_tmpl->check_initiator_node_acl()
   1406 * to locate struct se_node_acl
   1407 */
   1408static int tcm_qla2xxx_check_initiator_node_acl(
   1409	scsi_qla_host_t *vha,
   1410	unsigned char *fc_wwpn,
   1411	struct fc_port *qlat_sess)
   1412{
   1413	struct qla_hw_data *ha = vha->hw;
   1414	struct tcm_qla2xxx_lport *lport;
   1415	struct tcm_qla2xxx_tpg *tpg;
   1416	struct se_session *se_sess;
   1417	unsigned char port_name[36];
   1418	int num_tags = (ha->cur_fw_xcb_count) ? ha->cur_fw_xcb_count :
   1419		       TCM_QLA2XXX_DEFAULT_TAGS;
   1420
   1421	lport = vha->vha_tgt.target_lport_ptr;
   1422	if (!lport) {
   1423		pr_err("Unable to locate struct tcm_qla2xxx_lport\n");
   1424		dump_stack();
   1425		return -EINVAL;
   1426	}
   1427	/*
   1428	 * Locate the TPG=1 reference..
   1429	 */
   1430	tpg = lport->tpg_1;
   1431	if (!tpg) {
   1432		pr_err("Unable to locate struct tcm_qla2xxx_lport->tpg_1\n");
   1433		return -EINVAL;
   1434	}
   1435	/*
   1436	 * Format the FCP Initiator port_name into colon seperated values to
   1437	 * match the format by tcm_qla2xxx explict ConfigFS NodeACLs.
   1438	 */
   1439	memset(&port_name, 0, 36);
   1440	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
   1441	/*
   1442	 * Locate our struct se_node_acl either from an explict NodeACL created
   1443	 * via ConfigFS, or via running in TPG demo mode.
   1444	 */
   1445	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
   1446				       sizeof(struct qla_tgt_cmd),
   1447				       TARGET_PROT_ALL, port_name,
   1448				       qlat_sess, tcm_qla2xxx_session_cb);
   1449	if (IS_ERR(se_sess))
   1450		return PTR_ERR(se_sess);
   1451
   1452	return 0;
   1453}
   1454
   1455static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
   1456				    uint16_t loop_id, bool conf_compl_supported)
   1457{
   1458	struct qla_tgt *tgt = sess->tgt;
   1459	struct qla_hw_data *ha = tgt->ha;
   1460	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
   1461	struct tcm_qla2xxx_lport *lport = vha->vha_tgt.target_lport_ptr;
   1462	struct se_node_acl *se_nacl = sess->se_sess->se_node_acl;
   1463	struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
   1464			struct tcm_qla2xxx_nacl, se_node_acl);
   1465	u32 key;
   1466
   1467
   1468	if (sess->loop_id != loop_id || sess->d_id.b24 != s_id.b24)
   1469		pr_info("Updating session %p from port %8phC loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n",
   1470		    sess, sess->port_name,
   1471		    sess->loop_id, loop_id, sess->d_id.b.domain,
   1472		    sess->d_id.b.area, sess->d_id.b.al_pa, s_id.b.domain,
   1473		    s_id.b.area, s_id.b.al_pa);
   1474
   1475	if (sess->loop_id != loop_id) {
   1476		/*
   1477		 * Because we can shuffle loop IDs around and we
   1478		 * update different sessions non-atomically, we might
   1479		 * have overwritten this session's old loop ID
   1480		 * already, and we might end up overwriting some other
   1481		 * session that will be updated later.  So we have to
   1482		 * be extra careful and we can't warn about those things...
   1483		 */
   1484		if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl)
   1485			lport->lport_loopid_map[sess->loop_id].se_nacl = NULL;
   1486
   1487		lport->lport_loopid_map[loop_id].se_nacl = se_nacl;
   1488
   1489		sess->loop_id = loop_id;
   1490	}
   1491
   1492	if (sess->d_id.b24 != s_id.b24) {
   1493		key = (((u32) sess->d_id.b.domain << 16) |
   1494		       ((u32) sess->d_id.b.area   <<  8) |
   1495		       ((u32) sess->d_id.b.al_pa));
   1496
   1497		if (btree_lookup32(&lport->lport_fcport_map, key))
   1498			WARN(btree_remove32(&lport->lport_fcport_map, key) !=
   1499			    se_nacl, "Found wrong se_nacl when updating s_id %x:%x:%x\n",
   1500			    sess->d_id.b.domain, sess->d_id.b.area,
   1501			    sess->d_id.b.al_pa);
   1502		else
   1503			WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n",
   1504			     sess->d_id.b.domain, sess->d_id.b.area,
   1505			     sess->d_id.b.al_pa);
   1506
   1507		key = (((u32) s_id.b.domain << 16) |
   1508		       ((u32) s_id.b.area   <<  8) |
   1509		       ((u32) s_id.b.al_pa));
   1510
   1511		if (btree_lookup32(&lport->lport_fcport_map, key)) {
   1512			WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n",
   1513			     s_id.b.domain, s_id.b.area, s_id.b.al_pa);
   1514			btree_update32(&lport->lport_fcport_map, key, se_nacl);
   1515		} else {
   1516			btree_insert32(&lport->lport_fcport_map, key, se_nacl,
   1517			    GFP_ATOMIC);
   1518		}
   1519
   1520		sess->d_id = s_id;
   1521		nacl->nport_id = key;
   1522	}
   1523
   1524	sess->conf_compl_supported = conf_compl_supported;
   1525
   1526}
   1527
   1528/*
   1529 * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path.
   1530 */
   1531static const struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
   1532	.find_cmd_by_tag	= tcm_qla2xxx_find_cmd_by_tag,
   1533	.handle_cmd		= tcm_qla2xxx_handle_cmd,
   1534	.handle_data		= tcm_qla2xxx_handle_data,
   1535	.handle_tmr		= tcm_qla2xxx_handle_tmr,
   1536	.get_cmd		= tcm_qla2xxx_get_cmd,
   1537	.rel_cmd		= tcm_qla2xxx_rel_cmd,
   1538	.free_cmd		= tcm_qla2xxx_free_cmd,
   1539	.free_mcmd		= tcm_qla2xxx_free_mcmd,
   1540	.free_session		= tcm_qla2xxx_free_session,
   1541	.update_sess		= tcm_qla2xxx_update_sess,
   1542	.check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl,
   1543	.find_sess_by_s_id	= tcm_qla2xxx_find_sess_by_s_id,
   1544	.find_sess_by_loop_id	= tcm_qla2xxx_find_sess_by_loop_id,
   1545	.clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map,
   1546	.put_sess		= tcm_qla2xxx_put_sess,
   1547	.shutdown_sess		= tcm_qla2xxx_shutdown_sess,
   1548	.get_dif_tags		= tcm_qla2xxx_dif_tags,
   1549	.chk_dif_tags		= tcm_qla2xxx_chk_dif_tags,
   1550};
   1551
   1552static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
   1553{
   1554	int rc;
   1555
   1556	rc = btree_init32(&lport->lport_fcport_map);
   1557	if (rc) {
   1558		pr_err("Unable to initialize lport->lport_fcport_map btree\n");
   1559		return rc;
   1560	}
   1561
   1562	lport->lport_loopid_map =
   1563		vzalloc(array_size(65536,
   1564				   sizeof(struct tcm_qla2xxx_fc_loopid)));
   1565	if (!lport->lport_loopid_map) {
   1566		pr_err("Unable to allocate lport->lport_loopid_map of %zu bytes\n",
   1567		    sizeof(struct tcm_qla2xxx_fc_loopid) * 65536);
   1568		btree_destroy32(&lport->lport_fcport_map);
   1569		return -ENOMEM;
   1570	}
   1571	pr_debug("qla2xxx: Allocated lport_loopid_map of %zu bytes\n",
   1572	       sizeof(struct tcm_qla2xxx_fc_loopid) * 65536);
   1573	return 0;
   1574}
   1575
   1576static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha,
   1577					 void *target_lport_ptr,
   1578					 u64 npiv_wwpn, u64 npiv_wwnn)
   1579{
   1580	struct qla_hw_data *ha = vha->hw;
   1581	struct tcm_qla2xxx_lport *lport =
   1582			(struct tcm_qla2xxx_lport *)target_lport_ptr;
   1583	/*
   1584	 * Setup tgt_ops, local pointer to vha and target_lport_ptr
   1585	 */
   1586	ha->tgt.tgt_ops = &tcm_qla2xxx_template;
   1587	vha->vha_tgt.target_lport_ptr = target_lport_ptr;
   1588	lport->qla_vha = vha;
   1589
   1590	return 0;
   1591}
   1592
   1593static struct se_wwn *tcm_qla2xxx_make_lport(
   1594	struct target_fabric_configfs *tf,
   1595	struct config_group *group,
   1596	const char *name)
   1597{
   1598	struct tcm_qla2xxx_lport *lport;
   1599	u64 wwpn;
   1600	int ret = -ENODEV;
   1601
   1602	if (tcm_qla2xxx_parse_wwn(name, &wwpn, 1) < 0)
   1603		return ERR_PTR(-EINVAL);
   1604
   1605	lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL);
   1606	if (!lport) {
   1607		pr_err("Unable to allocate struct tcm_qla2xxx_lport\n");
   1608		return ERR_PTR(-ENOMEM);
   1609	}
   1610	lport->lport_wwpn = wwpn;
   1611	tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN,
   1612				wwpn);
   1613	sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn);
   1614
   1615	ret = tcm_qla2xxx_init_lport(lport);
   1616	if (ret != 0)
   1617		goto out;
   1618
   1619	ret = qlt_lport_register(lport, wwpn, 0, 0,
   1620				 tcm_qla2xxx_lport_register_cb);
   1621	if (ret != 0)
   1622		goto out_lport;
   1623
   1624	return &lport->lport_wwn;
   1625out_lport:
   1626	vfree(lport->lport_loopid_map);
   1627	btree_destroy32(&lport->lport_fcport_map);
   1628out:
   1629	kfree(lport);
   1630	return ERR_PTR(ret);
   1631}
   1632
   1633static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn)
   1634{
   1635	struct tcm_qla2xxx_lport *lport = container_of(wwn,
   1636			struct tcm_qla2xxx_lport, lport_wwn);
   1637	struct scsi_qla_host *vha = lport->qla_vha;
   1638	struct se_node_acl *node;
   1639	u32 key = 0;
   1640
   1641	/*
   1642	 * Call into qla2x_target.c LLD logic to complete the
   1643	 * shutdown of struct qla_tgt after the call to
   1644	 * qlt_stop_phase1() from tcm_qla2xxx_drop_tpg() above..
   1645	 */
   1646	if (vha->vha_tgt.qla_tgt && !vha->vha_tgt.qla_tgt->tgt_stopped)
   1647		qlt_stop_phase2(vha->vha_tgt.qla_tgt);
   1648
   1649	qlt_lport_deregister(vha);
   1650
   1651	vfree(lport->lport_loopid_map);
   1652	btree_for_each_safe32(&lport->lport_fcport_map, key, node)
   1653		btree_remove32(&lport->lport_fcport_map, key);
   1654	btree_destroy32(&lport->lport_fcport_map);
   1655	kfree(lport);
   1656}
   1657
   1658static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
   1659					      void *target_lport_ptr,
   1660					      u64 npiv_wwpn, u64 npiv_wwnn)
   1661{
   1662	struct fc_vport *vport;
   1663	struct Scsi_Host *sh = base_vha->host;
   1664	struct scsi_qla_host *npiv_vha;
   1665	struct tcm_qla2xxx_lport *lport =
   1666			(struct tcm_qla2xxx_lport *)target_lport_ptr;
   1667	struct tcm_qla2xxx_lport *base_lport =
   1668			(struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr;
   1669	struct fc_vport_identifiers vport_id;
   1670
   1671	if (qla_ini_mode_enabled(base_vha)) {
   1672		pr_err("qla2xxx base_vha not enabled for target mode\n");
   1673		return -EPERM;
   1674	}
   1675
   1676	if (!base_lport || !base_lport->tpg_1 ||
   1677	    !atomic_read(&base_lport->tpg_1->lport_tpg_enabled)) {
   1678		pr_err("qla2xxx base_lport or tpg_1 not available\n");
   1679		return -EPERM;
   1680	}
   1681
   1682	memset(&vport_id, 0, sizeof(vport_id));
   1683	vport_id.port_name = npiv_wwpn;
   1684	vport_id.node_name = npiv_wwnn;
   1685	vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR;
   1686	vport_id.vport_type = FC_PORTTYPE_NPIV;
   1687	vport_id.disable = false;
   1688
   1689	vport = fc_vport_create(sh, 0, &vport_id);
   1690	if (!vport) {
   1691		pr_err("fc_vport_create failed for qla2xxx_npiv\n");
   1692		return -ENODEV;
   1693	}
   1694	/*
   1695	 * Setup local pointer to NPIV vhba + target_lport_ptr
   1696	 */
   1697	npiv_vha = (struct scsi_qla_host *)vport->dd_data;
   1698	npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr;
   1699	lport->qla_vha = npiv_vha;
   1700	scsi_host_get(npiv_vha->host);
   1701	return 0;
   1702}
   1703
   1704
   1705static struct se_wwn *tcm_qla2xxx_npiv_make_lport(
   1706	struct target_fabric_configfs *tf,
   1707	struct config_group *group,
   1708	const char *name)
   1709{
   1710	struct tcm_qla2xxx_lport *lport;
   1711	u64 phys_wwpn, npiv_wwpn, npiv_wwnn;
   1712	char *p, tmp[128];
   1713	int ret;
   1714
   1715	snprintf(tmp, 128, "%s", name);
   1716
   1717	p = strchr(tmp, '@');
   1718	if (!p) {
   1719		pr_err("Unable to locate NPIV '@' separator\n");
   1720		return ERR_PTR(-EINVAL);
   1721	}
   1722	*p++ = '\0';
   1723
   1724	if (tcm_qla2xxx_parse_wwn(tmp, &phys_wwpn, 1) < 0)
   1725		return ERR_PTR(-EINVAL);
   1726
   1727	if (tcm_qla2xxx_npiv_parse_wwn(p, strlen(p)+1,
   1728				       &npiv_wwpn, &npiv_wwnn) < 0)
   1729		return ERR_PTR(-EINVAL);
   1730
   1731	lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL);
   1732	if (!lport) {
   1733		pr_err("Unable to allocate struct tcm_qla2xxx_lport for NPIV\n");
   1734		return ERR_PTR(-ENOMEM);
   1735	}
   1736	lport->lport_npiv_wwpn = npiv_wwpn;
   1737	lport->lport_npiv_wwnn = npiv_wwnn;
   1738	sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn);
   1739
   1740	ret = tcm_qla2xxx_init_lport(lport);
   1741	if (ret != 0)
   1742		goto out;
   1743
   1744	ret = qlt_lport_register(lport, phys_wwpn, npiv_wwpn, npiv_wwnn,
   1745				 tcm_qla2xxx_lport_register_npiv_cb);
   1746	if (ret != 0)
   1747		goto out_lport;
   1748
   1749	return &lport->lport_wwn;
   1750out_lport:
   1751	vfree(lport->lport_loopid_map);
   1752	btree_destroy32(&lport->lport_fcport_map);
   1753out:
   1754	kfree(lport);
   1755	return ERR_PTR(ret);
   1756}
   1757
   1758static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn)
   1759{
   1760	struct tcm_qla2xxx_lport *lport = container_of(wwn,
   1761			struct tcm_qla2xxx_lport, lport_wwn);
   1762	struct scsi_qla_host *npiv_vha = lport->qla_vha;
   1763	struct qla_hw_data *ha = npiv_vha->hw;
   1764	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
   1765
   1766	scsi_host_put(npiv_vha->host);
   1767	/*
   1768	 * Notify libfc that we want to release the vha->fc_vport
   1769	 */
   1770	fc_vport_terminate(npiv_vha->fc_vport);
   1771	scsi_host_put(base_vha->host);
   1772	kfree(lport);
   1773}
   1774
   1775
   1776static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
   1777		char *page)
   1778{
   1779	return sprintf(page,
   1780	    "TCM QLOGIC QLA2XXX NPIV capable fabric module %s on %s/%s on %s\n",
   1781	    QLA2XXX_VERSION, utsname()->sysname,
   1782	    utsname()->machine, utsname()->release);
   1783}
   1784
   1785CONFIGFS_ATTR_RO(tcm_qla2xxx_wwn_, version);
   1786
   1787static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = {
   1788	&tcm_qla2xxx_wwn_attr_version,
   1789	NULL,
   1790};
   1791
   1792static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
   1793	.module				= THIS_MODULE,
   1794	.fabric_name			= "qla2xxx",
   1795	.node_acl_size			= sizeof(struct tcm_qla2xxx_nacl),
   1796	/*
   1797	 * XXX: Limit assumes single page per scatter-gather-list entry.
   1798	 * Current maximum is ~4.9 MB per se_cmd->t_data_sg with PAGE_SIZE=4096
   1799	 */
   1800	.max_data_sg_nents		= 1200,
   1801	.tpg_get_wwn			= tcm_qla2xxx_get_fabric_wwn,
   1802	.tpg_get_tag			= tcm_qla2xxx_get_tag,
   1803	.tpg_check_demo_mode		= tcm_qla2xxx_check_demo_mode,
   1804	.tpg_check_demo_mode_cache	= tcm_qla2xxx_check_demo_mode_cache,
   1805	.tpg_check_demo_mode_write_protect =
   1806					tcm_qla2xxx_check_demo_write_protect,
   1807	.tpg_check_prod_mode_write_protect =
   1808					tcm_qla2xxx_check_prod_write_protect,
   1809	.tpg_check_prot_fabric_only	= tcm_qla2xxx_check_prot_fabric_only,
   1810	.tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only,
   1811	.tpg_get_inst_index		= tcm_qla2xxx_tpg_get_inst_index,
   1812	.check_stop_free		= tcm_qla2xxx_check_stop_free,
   1813	.release_cmd			= tcm_qla2xxx_release_cmd,
   1814	.close_session			= tcm_qla2xxx_close_session,
   1815	.sess_get_index			= tcm_qla2xxx_sess_get_index,
   1816	.sess_get_initiator_sid		= NULL,
   1817	.write_pending			= tcm_qla2xxx_write_pending,
   1818	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
   1819	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
   1820	.queue_data_in			= tcm_qla2xxx_queue_data_in,
   1821	.queue_status			= tcm_qla2xxx_queue_status,
   1822	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
   1823	.aborted_task			= tcm_qla2xxx_aborted_task,
   1824	/*
   1825	 * Setup function pointers for generic logic in
   1826	 * target_core_fabric_configfs.c
   1827	 */
   1828	.fabric_make_wwn		= tcm_qla2xxx_make_lport,
   1829	.fabric_drop_wwn		= tcm_qla2xxx_drop_lport,
   1830	.fabric_make_tpg		= tcm_qla2xxx_make_tpg,
   1831	.fabric_enable_tpg		= tcm_qla2xxx_enable_tpg,
   1832	.fabric_drop_tpg		= tcm_qla2xxx_drop_tpg,
   1833	.fabric_init_nodeacl		= tcm_qla2xxx_init_nodeacl,
   1834
   1835	.tfc_wwn_attrs			= tcm_qla2xxx_wwn_attrs,
   1836	.tfc_tpg_base_attrs		= tcm_qla2xxx_tpg_attrs,
   1837	.tfc_tpg_attrib_attrs		= tcm_qla2xxx_tpg_attrib_attrs,
   1838};
   1839
   1840static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
   1841	.module				= THIS_MODULE,
   1842	.fabric_name			= "qla2xxx_npiv",
   1843	.node_acl_size			= sizeof(struct tcm_qla2xxx_nacl),
   1844	.tpg_get_wwn			= tcm_qla2xxx_get_fabric_wwn,
   1845	.tpg_get_tag			= tcm_qla2xxx_get_tag,
   1846	.tpg_check_demo_mode		= tcm_qla2xxx_check_demo_mode,
   1847	.tpg_check_demo_mode_cache	= tcm_qla2xxx_check_demo_mode_cache,
   1848	.tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_demo_mode,
   1849	.tpg_check_prod_mode_write_protect =
   1850	    tcm_qla2xxx_check_prod_write_protect,
   1851	.tpg_check_demo_mode_login_only	= tcm_qla2xxx_check_demo_mode_login_only,
   1852	.tpg_get_inst_index		= tcm_qla2xxx_tpg_get_inst_index,
   1853	.check_stop_free                = tcm_qla2xxx_check_stop_free,
   1854	.release_cmd			= tcm_qla2xxx_release_cmd,
   1855	.close_session			= tcm_qla2xxx_close_session,
   1856	.sess_get_index			= tcm_qla2xxx_sess_get_index,
   1857	.sess_get_initiator_sid		= NULL,
   1858	.write_pending			= tcm_qla2xxx_write_pending,
   1859	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
   1860	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
   1861	.queue_data_in			= tcm_qla2xxx_queue_data_in,
   1862	.queue_status			= tcm_qla2xxx_queue_status,
   1863	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
   1864	.aborted_task			= tcm_qla2xxx_aborted_task,
   1865	/*
   1866	 * Setup function pointers for generic logic in
   1867	 * target_core_fabric_configfs.c
   1868	 */
   1869	.fabric_make_wwn		= tcm_qla2xxx_npiv_make_lport,
   1870	.fabric_drop_wwn		= tcm_qla2xxx_npiv_drop_lport,
   1871	.fabric_make_tpg		= tcm_qla2xxx_npiv_make_tpg,
   1872	.fabric_enable_tpg		= tcm_qla2xxx_npiv_enable_tpg,
   1873	.fabric_drop_tpg		= tcm_qla2xxx_drop_tpg,
   1874	.fabric_init_nodeacl		= tcm_qla2xxx_init_nodeacl,
   1875
   1876	.tfc_wwn_attrs			= tcm_qla2xxx_wwn_attrs,
   1877};
   1878
   1879static int tcm_qla2xxx_register_configfs(void)
   1880{
   1881	int ret;
   1882
   1883	pr_debug("TCM QLOGIC QLA2XXX fabric module %s on %s/%s on %s\n",
   1884	    QLA2XXX_VERSION, utsname()->sysname,
   1885	    utsname()->machine, utsname()->release);
   1886
   1887	ret = target_register_template(&tcm_qla2xxx_ops);
   1888	if (ret)
   1889		return ret;
   1890
   1891	ret = target_register_template(&tcm_qla2xxx_npiv_ops);
   1892	if (ret)
   1893		goto out_fabric;
   1894
   1895	tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free",
   1896						WQ_MEM_RECLAIM, 0);
   1897	if (!tcm_qla2xxx_free_wq) {
   1898		ret = -ENOMEM;
   1899		goto out_fabric_npiv;
   1900	}
   1901
   1902	return 0;
   1903
   1904out_fabric_npiv:
   1905	target_unregister_template(&tcm_qla2xxx_npiv_ops);
   1906out_fabric:
   1907	target_unregister_template(&tcm_qla2xxx_ops);
   1908	return ret;
   1909}
   1910
   1911static void tcm_qla2xxx_deregister_configfs(void)
   1912{
   1913	destroy_workqueue(tcm_qla2xxx_free_wq);
   1914
   1915	target_unregister_template(&tcm_qla2xxx_ops);
   1916	target_unregister_template(&tcm_qla2xxx_npiv_ops);
   1917}
   1918
   1919static int __init tcm_qla2xxx_init(void)
   1920{
   1921	int ret;
   1922
   1923	BUILD_BUG_ON(sizeof(struct abts_recv_from_24xx) != 64);
   1924	BUILD_BUG_ON(sizeof(struct abts_resp_from_24xx_fw) != 64);
   1925	BUILD_BUG_ON(sizeof(struct atio7_fcp_cmnd) != 32);
   1926	BUILD_BUG_ON(sizeof(struct atio_from_isp) != 64);
   1927	BUILD_BUG_ON(sizeof(struct ba_acc_le) != 12);
   1928	BUILD_BUG_ON(sizeof(struct ba_rjt_le) != 4);
   1929	BUILD_BUG_ON(sizeof(struct ctio7_from_24xx) != 64);
   1930	BUILD_BUG_ON(sizeof(struct ctio7_to_24xx) != 64);
   1931	BUILD_BUG_ON(sizeof(struct ctio_crc2_to_fw) != 64);
   1932	BUILD_BUG_ON(sizeof(struct ctio_crc_from_fw) != 64);
   1933	BUILD_BUG_ON(sizeof(struct ctio_to_2xxx) != 64);
   1934	BUILD_BUG_ON(sizeof(struct fcp_hdr) != 24);
   1935	BUILD_BUG_ON(sizeof(struct fcp_hdr_le) != 24);
   1936	BUILD_BUG_ON(sizeof(struct nack_to_isp) != 64);
   1937
   1938	ret = tcm_qla2xxx_register_configfs();
   1939	if (ret < 0)
   1940		return ret;
   1941
   1942	return 0;
   1943}
   1944
   1945static void __exit tcm_qla2xxx_exit(void)
   1946{
   1947	tcm_qla2xxx_deregister_configfs();
   1948}
   1949
   1950MODULE_DESCRIPTION("TCM QLA24XX+ series NPIV enabled fabric driver");
   1951MODULE_LICENSE("GPL");
   1952module_init(tcm_qla2xxx_init);
   1953module_exit(tcm_qla2xxx_exit);