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