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