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