This source file includes following definitions.
- tcm_qla2xxx_parse_wwn
- tcm_qla2xxx_format_wwn
- tcm_qla2xxx_npiv_extract_wwn
- tcm_qla2xxx_npiv_parse_wwn
- tcm_qla2xxx_get_fabric_wwn
- tcm_qla2xxx_get_tag
- tcm_qla2xxx_check_demo_mode
- tcm_qla2xxx_check_demo_mode_cache
- tcm_qla2xxx_check_demo_write_protect
- tcm_qla2xxx_check_prod_write_protect
- tcm_qla2xxx_check_demo_mode_login_only
- tcm_qla2xxx_check_prot_fabric_only
- tcm_qla2xxx_tpg_get_inst_index
- tcm_qla2xxx_complete_mcmd
- tcm_qla2xxx_free_mcmd
- tcm_qla2xxx_complete_free
- tcm_qla2xxx_free_cmd
- tcm_qla2xxx_check_stop_free
- tcm_qla2xxx_release_cmd
- tcm_qla2xxx_release_session
- tcm_qla2xxx_put_sess
- tcm_qla2xxx_close_session
- tcm_qla2xxx_sess_get_index
- tcm_qla2xxx_write_pending
- tcm_qla2xxx_set_default_node_attrs
- tcm_qla2xxx_get_cmd_state
- tcm_qla2xxx_handle_cmd
- tcm_qla2xxx_handle_data_work
- tcm_qla2xxx_handle_data
- tcm_qla2xxx_chk_dif_tags
- tcm_qla2xxx_dif_tags
- tcm_qla2xxx_handle_tmr
- tcm_qla2xxx_find_cmd_by_tag
- tcm_qla2xxx_queue_data_in
- tcm_qla2xxx_queue_status
- tcm_qla2xxx_queue_tm_rsp
- tcm_qla2xxx_aborted_task
- tcm_qla2xxx_clear_nacl_from_fcport_map
- tcm_qla2xxx_shutdown_sess
- tcm_qla2xxx_init_nodeacl
- tcm_qla2xxx_tpg_enable_show
- tcm_qla2xxx_tpg_enable_store
- tcm_qla2xxx_tpg_dynamic_sessions_show
- tcm_qla2xxx_tpg_fabric_prot_type_store
- tcm_qla2xxx_tpg_fabric_prot_type_show
- tcm_qla2xxx_make_tpg
- tcm_qla2xxx_drop_tpg
- tcm_qla2xxx_npiv_tpg_enable_show
- tcm_qla2xxx_npiv_tpg_enable_store
- tcm_qla2xxx_npiv_make_tpg
- tcm_qla2xxx_find_sess_by_s_id
- tcm_qla2xxx_set_sess_by_s_id
- tcm_qla2xxx_find_sess_by_loop_id
- tcm_qla2xxx_set_sess_by_loop_id
- tcm_qla2xxx_clear_sess_lookup
- tcm_qla2xxx_free_session
- tcm_qla2xxx_session_cb
- tcm_qla2xxx_check_initiator_node_acl
- tcm_qla2xxx_update_sess
- tcm_qla2xxx_init_lport
- tcm_qla2xxx_lport_register_cb
- tcm_qla2xxx_make_lport
- tcm_qla2xxx_drop_lport
- tcm_qla2xxx_lport_register_npiv_cb
- tcm_qla2xxx_npiv_make_lport
- tcm_qla2xxx_npiv_drop_lport
- tcm_qla2xxx_wwn_version_show
- tcm_qla2xxx_register_configfs
- tcm_qla2xxx_deregister_configfs
- tcm_qla2xxx_init
- tcm_qla2xxx_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  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 
  40 
  41 
  42 
  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 
  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         
 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 
 129 
 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         
 144         if (name[cnt-1] == '\n' || name[cnt-1] == 0)
 145                 cnt--;
 146 
 147         
 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 
 244 
 245 
 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         
 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 
 273 
 274 
 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 
 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 
 304 
 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                 
 369 
 370 
 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 
 396 
 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 
 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                 
 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 
 472 
 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 
 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 
 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                 
 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                 
 630 
 631 
 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 
 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 
 673 
 674 
 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 
 694 
 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 
 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 
 721 
 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 
 740 
 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 
 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 
 776 
 777 
 778 
 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 
 788 
 789 
 790 
 791 
 792 
 793 
 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 
 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 
 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 
1011 
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 
1038 
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 
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 
1127 
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 
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 
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 
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 
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 
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 
1408 
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 
1422 
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 
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 
1453 
1454 
1455         memset(&port_name, 0, 36);
1456         snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
1457         
1458 
1459 
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 
1494 
1495 
1496 
1497 
1498 
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 
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 
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 
1657 
1658 
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 
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 
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 
1812 
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 
1840 
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 
1880 
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);