root/drivers/scsi/qla2xxx/tcm_qla2xxx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tcm_qla2xxx_parse_wwn
  2. tcm_qla2xxx_format_wwn
  3. tcm_qla2xxx_npiv_extract_wwn
  4. tcm_qla2xxx_npiv_parse_wwn
  5. tcm_qla2xxx_get_fabric_wwn
  6. tcm_qla2xxx_get_tag
  7. tcm_qla2xxx_check_demo_mode
  8. tcm_qla2xxx_check_demo_mode_cache
  9. tcm_qla2xxx_check_demo_write_protect
  10. tcm_qla2xxx_check_prod_write_protect
  11. tcm_qla2xxx_check_demo_mode_login_only
  12. tcm_qla2xxx_check_prot_fabric_only
  13. tcm_qla2xxx_tpg_get_inst_index
  14. tcm_qla2xxx_complete_mcmd
  15. tcm_qla2xxx_free_mcmd
  16. tcm_qla2xxx_complete_free
  17. tcm_qla2xxx_free_cmd
  18. tcm_qla2xxx_check_stop_free
  19. tcm_qla2xxx_release_cmd
  20. tcm_qla2xxx_release_session
  21. tcm_qla2xxx_put_sess
  22. tcm_qla2xxx_close_session
  23. tcm_qla2xxx_sess_get_index
  24. tcm_qla2xxx_write_pending
  25. tcm_qla2xxx_set_default_node_attrs
  26. tcm_qla2xxx_get_cmd_state
  27. tcm_qla2xxx_handle_cmd
  28. tcm_qla2xxx_handle_data_work
  29. tcm_qla2xxx_handle_data
  30. tcm_qla2xxx_chk_dif_tags
  31. tcm_qla2xxx_dif_tags
  32. tcm_qla2xxx_handle_tmr
  33. tcm_qla2xxx_find_cmd_by_tag
  34. tcm_qla2xxx_queue_data_in
  35. tcm_qla2xxx_queue_status
  36. tcm_qla2xxx_queue_tm_rsp
  37. tcm_qla2xxx_aborted_task
  38. tcm_qla2xxx_clear_nacl_from_fcport_map
  39. tcm_qla2xxx_shutdown_sess
  40. tcm_qla2xxx_init_nodeacl
  41. tcm_qla2xxx_tpg_enable_show
  42. tcm_qla2xxx_tpg_enable_store
  43. tcm_qla2xxx_tpg_dynamic_sessions_show
  44. tcm_qla2xxx_tpg_fabric_prot_type_store
  45. tcm_qla2xxx_tpg_fabric_prot_type_show
  46. tcm_qla2xxx_make_tpg
  47. tcm_qla2xxx_drop_tpg
  48. tcm_qla2xxx_npiv_tpg_enable_show
  49. tcm_qla2xxx_npiv_tpg_enable_store
  50. tcm_qla2xxx_npiv_make_tpg
  51. tcm_qla2xxx_find_sess_by_s_id
  52. tcm_qla2xxx_set_sess_by_s_id
  53. tcm_qla2xxx_find_sess_by_loop_id
  54. tcm_qla2xxx_set_sess_by_loop_id
  55. tcm_qla2xxx_clear_sess_lookup
  56. tcm_qla2xxx_free_session
  57. tcm_qla2xxx_session_cb
  58. tcm_qla2xxx_check_initiator_node_acl
  59. tcm_qla2xxx_update_sess
  60. tcm_qla2xxx_init_lport
  61. tcm_qla2xxx_lport_register_cb
  62. tcm_qla2xxx_make_lport
  63. tcm_qla2xxx_drop_lport
  64. tcm_qla2xxx_lport_register_npiv_cb
  65. tcm_qla2xxx_npiv_make_lport
  66. tcm_qla2xxx_npiv_drop_lport
  67. tcm_qla2xxx_wwn_version_show
  68. tcm_qla2xxx_register_configfs
  69. tcm_qla2xxx_deregister_configfs
  70. tcm_qla2xxx_init
  71. tcm_qla2xxx_exit

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

/* [<][>][^][v][top][bottom][index][help] */