mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-21 12:41:26 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -1,4 +1,15 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
-include $(KBUILD_EXTMOD)/../build_mode
|
||||
|
||||
echo := $(shell echo "qla2x00t-32gbit build mode: $(BUILD_MODE)" >& 2)
|
||||
|
||||
BUILD_MODE_CFLAGS_ = -DCONFIG_SCST_TRACING -DCONFIG_SCST_DEBUG \
|
||||
-DCONFIG_SCST_EXTRACHECKS -fno-inline -fno-inline-functions
|
||||
BUILD_MODE_CFLAGS_RELEASE = -DCONFIG_SCST_TRACING
|
||||
BUILD_MODE_CFLAGS_PERF =
|
||||
ccflags-y += $(BUILD_MODE_CFLAGS_$(BUILD_MODE))
|
||||
|
||||
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
|
||||
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
|
||||
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o
|
||||
|
||||
@@ -67,7 +67,7 @@ ccflags-y += -W -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
-include $(KBUILD_EXTMOD)/../../build_mode
|
||||
|
||||
echo := $(shell echo "qla2x00t-32gbit build mode: $(BUILD_MODE)" >& 2)
|
||||
echo := $(shell echo "qla2x00t-32gbit/target build mode: $(BUILD_MODE)" >& 2)
|
||||
|
||||
BUILD_MODE_CFLAGS_ = -DCONFIG_SCST_TRACING -DCONFIG_SCST_DEBUG \
|
||||
-DCONFIG_SCST_EXTRACHECKS -fno-inline -fno-inline-functions
|
||||
|
||||
@@ -68,32 +68,3 @@ Call Trace:
|
||||
[<ffffffff8159c459>] ? retint_restore_args+0x13/0x43
|
||||
[<ffffffff810b2480>] ? kthread+0x0/0xc0
|
||||
[<ffffffff8159cc40>] ? child_rip+0x0/0x30
|
||||
|
||||
When using RHEL 6 unloading this driver triggers a deadlock:
|
||||
|
||||
INFO: task events/0:35 blocked for more than 120 seconds.
|
||||
Not tainted 2.6.32-754.11.1.el6.x86_64.debug #1
|
||||
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
|
||||
events/0 D ffff880077e24408 12408 35 2 0x00000000
|
||||
ffff88007e02fa60 0000000000000046 0000000000000000 7fffffffffffffff
|
||||
7fffffffffffffff 00000365a5588f80 ffff88007e028a80 ffff88000d7d93d8
|
||||
0000000100346a5e 00000000000003c8 ffff88007e029040 ffff88007e02ffd8
|
||||
Call Trace:
|
||||
[<ffffffff8158f775>] schedule_timeout+0x265/0x330
|
||||
[<ffffffff8158f29f>] ? wait_for_common+0x4f/0x180
|
||||
[<ffffffff8158f29f>] ? wait_for_common+0x4f/0x180
|
||||
[<ffffffff810737a0>] ? default_wake_function+0x0/0x20
|
||||
[<ffffffff8158f37b>] wait_for_common+0x12b/0x180
|
||||
[<ffffffff810737a0>] ? default_wake_function+0x0/0x20
|
||||
[<ffffffff8158f4ad>] wait_for_completion+0x1d/0x20
|
||||
[<ffffffffa0714946>] ? qlt_free_session_done+0x1d6/0x930 [qla2xxx_scst]
|
||||
[<ffffffffa0714770>] ? qlt_free_session_done+0x0/0x930 [qla2xxx_scst]
|
||||
[<ffffffff810ab2ee>] ? worker_thread+0x21e/0x3f0
|
||||
[<ffffffff810ab29b>] ? worker_thread+0x1cb/0x3f0
|
||||
[<ffffffff810b29b0>] ? autoremove_wake_function+0x0/0x40
|
||||
[<ffffffff810ab0d0>] ? worker_thread+0x0/0x3f0
|
||||
[<ffffffff810b2520>] ? kthread+0xa0/0xc0
|
||||
[<ffffffff8159cc60>] ? child_rip+0x20/0x30
|
||||
[<ffffffff8159c459>] ? retint_restore_args+0x13/0x43
|
||||
[<ffffffff810b2480>] ? kthread+0x0/0xc0
|
||||
[<ffffffff8159cc40>] ? child_rip+0x0/0x30
|
||||
|
||||
@@ -100,39 +100,6 @@ static bool sqa_is_tgt_enabled(struct scst_tgt *tgt);
|
||||
static ssize_t sqa_add_vtarget(const char *target_name, char *params);
|
||||
static ssize_t sqa_del_vtarget(const char *target_name);
|
||||
|
||||
/*
|
||||
* Function definitions for callbacks from the Cavium low level target
|
||||
* driver.
|
||||
*/
|
||||
static int sqa_qla2xxx_handle_cmd(scsi_qla_host_t *vha,
|
||||
struct qla_tgt_cmd *cmd,unsigned char *cdb,
|
||||
uint32_t data_length, int task_codes,
|
||||
int data_dir, int bidi);
|
||||
static void sqa_qla2xxx_handle_data(struct qla_tgt_cmd *cmd);
|
||||
static int sqa_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
|
||||
uint16_t tmr_func, uint32_t tag);
|
||||
static void sqa_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd);
|
||||
static void sqa_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd);
|
||||
static void sqa_qla2xxx_free_session(struct fc_port *sess);
|
||||
static void sqa_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
|
||||
uint16_t loop_id,
|
||||
bool conf_compl_supported);
|
||||
static int sqa_qla2xxx_check_initiator_node_acl(scsi_qla_host_t *vha,
|
||||
unsigned char *fc_wwpn,
|
||||
struct fc_port *qlat_sess);
|
||||
static struct fc_port *sqa_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha,
|
||||
const uint8_t *s_id);
|
||||
static struct fc_port *sqa_qla2xxx_find_sess_by_loop_id(scsi_qla_host_t *vha,
|
||||
const uint16_t loop_id);
|
||||
static void sqa_qla2xxx_clear_nacl_from_fcport_map(struct fc_port *sess);
|
||||
static void sqa_qla2xxx_put_sess(struct fc_port *sess);
|
||||
static void sqa_qla2xxx_shutdown_sess(struct fc_port *sess);
|
||||
static int sqa_close_session(struct scst_session *scst_sess);
|
||||
static int sqa_qla2xxx_dif_tags(struct qla_tgt_cmd *, uint16_t *);
|
||||
static int sqa_qla2xxx_chk_dif_tags(uint32_t);
|
||||
static void sqa_qla2xxx_add_target(struct scsi_qla_host *vha);
|
||||
static void sqa_qla2xxx_remove_target(struct scsi_qla_host *vha);
|
||||
|
||||
/* Definitions for helper functions. */
|
||||
static int sqa_get_target_name(uint8_t *wwn, char **ppwwn_name);
|
||||
static int sqa_parse_wwn(const char *ns, u64 *nm);
|
||||
@@ -244,60 +211,6 @@ static char *cmdstate_to_str(uint8_t state)
|
||||
return cmd_str[0].str; /* unknown */
|
||||
}
|
||||
|
||||
/*
|
||||
* The following structure definition provides descriptive parameeters
|
||||
* and callbacks which will be used by the SCST target core to
|
||||
* communicate with this target interface driver.
|
||||
*/
|
||||
static struct scst_tgt_template sqa_scst_template = {
|
||||
.name = "qla2x00t",
|
||||
.sg_tablesize = 0,
|
||||
.use_clustering = 1,
|
||||
#ifdef CONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
|
||||
.xmit_response_atomic = 0,
|
||||
.rdy_to_xfer_atomic = 0,
|
||||
#else
|
||||
.xmit_response_atomic = 1,
|
||||
.rdy_to_xfer_atomic = 1,
|
||||
#endif
|
||||
|
||||
#if QLA_ENABLE_PI
|
||||
/* diff cap for individual adapter is set during sqa_qla2xxx_add_target */
|
||||
.dif_supported = 0,
|
||||
.hw_dif_type1_supported = 0,
|
||||
.hw_dif_type2_supported = 0,
|
||||
.hw_dif_type3_supported = 0,
|
||||
.hw_dif_ip_supported = 0,
|
||||
.hw_dif_same_sg_layout_required = 0,
|
||||
#endif
|
||||
|
||||
.max_hw_pending_time = SQA_MAX_HW_PENDING_TIME,
|
||||
.release = sqa_target_release,
|
||||
|
||||
.xmit_response = sqa_xmit_response,
|
||||
.rdy_to_xfer = sqa_rdy_to_xfer,
|
||||
|
||||
.on_free_cmd = sqa_on_free_cmd,
|
||||
.task_mgmt_fn_done = sqa_task_mgmt_fn_done,
|
||||
.close_session = sqa_close_session,
|
||||
|
||||
.get_initiator_port_transport_id = sqa_get_initiator_port_transport_id,
|
||||
.get_scsi_transport_version = sqa_get_scsi_transport_version,
|
||||
.get_phys_transport_version = sqa_get_phys_transport_version,
|
||||
.on_hw_pending_cmd_timeout = sqa_on_hw_pending_cmd_timeout,
|
||||
.enable_target = sqa_enable_tgt,
|
||||
.is_target_enabled = sqa_is_tgt_enabled,
|
||||
.add_target = sqa_add_vtarget,
|
||||
.del_target = sqa_del_vtarget,
|
||||
.add_target_parameters = "node_name, parent_host",
|
||||
.tgtt_attrs = sqa_attrs,
|
||||
.tgt_attrs = sqa_tgt_attrs,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SQA_DEFAULT_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if QLA_ENABLE_PI
|
||||
|
||||
static const int qla_tgt_supported_dif_block_size[]= {
|
||||
@@ -491,32 +404,6 @@ static struct qla_tgt_cmd *sqa_qla2xxx_get_cmd(struct fc_port *sess)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following structure defines the callbacks which will be executed
|
||||
* from functions in the qla_target.c file back to this interface
|
||||
* driver.
|
||||
*/
|
||||
static struct qla_tgt_func_tmpl sqa_qla2xxx_template = {
|
||||
.handle_cmd = sqa_qla2xxx_handle_cmd,
|
||||
.handle_data = sqa_qla2xxx_handle_data,
|
||||
.handle_tmr = sqa_qla2xxx_handle_tmr,
|
||||
.get_cmd = sqa_qla2xxx_get_cmd,
|
||||
.free_cmd = sqa_qla2xxx_free_cmd,
|
||||
.free_mcmd = sqa_qla2xxx_free_mcmd,
|
||||
.free_session = sqa_qla2xxx_free_session,
|
||||
.update_sess = sqa_qla2xxx_update_sess,
|
||||
.check_initiator_node_acl = sqa_qla2xxx_check_initiator_node_acl,
|
||||
.find_sess_by_s_id = sqa_qla2xxx_find_sess_by_s_id,
|
||||
.find_sess_by_loop_id = sqa_qla2xxx_find_sess_by_loop_id,
|
||||
.clear_nacl_from_fcport_map = sqa_qla2xxx_clear_nacl_from_fcport_map,
|
||||
.put_sess = sqa_qla2xxx_put_sess,
|
||||
.shutdown_sess = sqa_qla2xxx_shutdown_sess,
|
||||
.get_dif_tags = sqa_qla2xxx_dif_tags,
|
||||
.chk_dif_tags = sqa_qla2xxx_chk_dif_tags,
|
||||
.add_target = sqa_qla2xxx_add_target,
|
||||
.remove_target = sqa_qla2xxx_remove_target,
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(sqa_mutex);
|
||||
|
||||
|
||||
@@ -862,11 +749,11 @@ static void sqa_qla2xxx_free_session(struct fc_port *fcport)
|
||||
wwn_to_str(fcport->port_name));
|
||||
}
|
||||
|
||||
scst_unregister_session(scst_sess, 1, sqa_free_session_done);
|
||||
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(c);
|
||||
|
||||
fcport->unreg_done = &c;
|
||||
scst_unregister_session(scst_sess, 1, sqa_free_session_done);
|
||||
wait_for_completion(&c);
|
||||
}
|
||||
|
||||
@@ -1041,7 +928,6 @@ static void sqa_qla2xxx_put_sess(struct fc_port *sess)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
|
||||
kref_put(&sess->sess_kref, sqa_qla2xxx_release_sess);
|
||||
|
||||
TRACE_EXIT();
|
||||
@@ -1358,26 +1244,12 @@ static ssize_t sqa_abort_isp_store(struct kobject *kobj,
|
||||
|
||||
static int sqa_get_target_name(uint8_t *wwn, char **ppwwn_name)
|
||||
{
|
||||
const int wwn_len = 3*WWN_SIZE+2;
|
||||
int res = 0;
|
||||
char *name;
|
||||
*ppwwn_name = kasprintf(GFP_KERNEL,
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
wwn[0], wwn[1], wwn[2], wwn[3],
|
||||
wwn[4], wwn[5], wwn[6], wwn[7]);
|
||||
|
||||
name = kmalloc(wwn_len, GFP_KERNEL);
|
||||
if (name == NULL) {
|
||||
PRINT_ERROR("sqatgt: Allocation of tgt wwn name (size %d) "
|
||||
"failed", wwn_len);
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(name, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
wwn[0], wwn[1], wwn[2], wwn[3],
|
||||
wwn[4], wwn[5], wwn[6], wwn[7]);
|
||||
|
||||
*ppwwn_name = name;
|
||||
|
||||
out:
|
||||
return res;
|
||||
return *ppwwn_name ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int sqa_parse_wwn(const char *ns, u64 *nm)
|
||||
@@ -1414,10 +1286,64 @@ static int sqa_parse_wwn(const char *ns, u64 *nm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following structure definition provides descriptive parameeters
|
||||
* and callbacks which will be used by the SCST target core to
|
||||
* communicate with this target interface driver.
|
||||
*/
|
||||
static struct scst_tgt_template sqa_scst_template = {
|
||||
.name = "qla2x00t",
|
||||
.sg_tablesize = 0,
|
||||
.use_clustering = 1,
|
||||
#ifdef CONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
|
||||
.xmit_response_atomic = 0,
|
||||
.rdy_to_xfer_atomic = 0,
|
||||
#else
|
||||
.xmit_response_atomic = 1,
|
||||
.rdy_to_xfer_atomic = 1,
|
||||
#endif
|
||||
|
||||
#if QLA_ENABLE_PI
|
||||
/* diff cap for individual adapter is set during sqa_qla2xxx_add_target */
|
||||
.dif_supported = 0,
|
||||
.hw_dif_type1_supported = 0,
|
||||
.hw_dif_type2_supported = 0,
|
||||
.hw_dif_type3_supported = 0,
|
||||
.hw_dif_ip_supported = 0,
|
||||
.hw_dif_same_sg_layout_required = 0,
|
||||
#endif
|
||||
|
||||
.max_hw_pending_time = SQA_MAX_HW_PENDING_TIME,
|
||||
.release = sqa_target_release,
|
||||
|
||||
.xmit_response = sqa_xmit_response,
|
||||
.rdy_to_xfer = sqa_rdy_to_xfer,
|
||||
|
||||
.on_free_cmd = sqa_on_free_cmd,
|
||||
.task_mgmt_fn_done = sqa_task_mgmt_fn_done,
|
||||
.close_session = sqa_close_session,
|
||||
|
||||
.get_initiator_port_transport_id = sqa_get_initiator_port_transport_id,
|
||||
.get_scsi_transport_version = sqa_get_scsi_transport_version,
|
||||
.get_phys_transport_version = sqa_get_phys_transport_version,
|
||||
.on_hw_pending_cmd_timeout = sqa_on_hw_pending_cmd_timeout,
|
||||
.enable_target = sqa_enable_tgt,
|
||||
.is_target_enabled = sqa_is_tgt_enabled,
|
||||
.add_target = sqa_add_vtarget,
|
||||
.del_target = sqa_del_vtarget,
|
||||
.add_target_parameters = "node_name, parent_host",
|
||||
.tgtt_attrs = sqa_attrs,
|
||||
.tgt_attrs = sqa_tgt_attrs,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SQA_DEFAULT_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* call must hold sqa_mutex */
|
||||
static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
{
|
||||
char *pwwn;
|
||||
char *pwwn = NULL;
|
||||
int res;
|
||||
struct scst_tgt *scst_tgt;
|
||||
struct sqa_scst_tgt *sqa_tgt;
|
||||
@@ -1435,7 +1361,6 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
if (!sqa_tgt) {
|
||||
PRINT_ERROR("sqatgt(%ld/%d): alloc sqa_tgt failed",
|
||||
vha->host_no, vha->vp_idx);
|
||||
kfree(pwwn);
|
||||
res = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
@@ -1444,7 +1369,6 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
if (!sqa_tgt->tgt_cmd_map) {
|
||||
PRINT_ERROR("sqatgt(%ld/%d): alloc tgt_cmd_map failed",
|
||||
vha->host_no, vha->vp_idx);
|
||||
kfree(pwwn);
|
||||
kfree(sqa_tgt);
|
||||
res = -ENOMEM;
|
||||
goto done;
|
||||
@@ -1465,7 +1389,6 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
pr_err("Unable to init se_sess->tgt_tag_pool,"
|
||||
" tag_num: %u\n", tag_num);
|
||||
kvfree(sqa_tgt->tgt_cmd_map);
|
||||
kfree(pwwn);
|
||||
kfree(sqa_tgt);
|
||||
goto done;
|
||||
}
|
||||
@@ -1478,7 +1401,6 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
PRINT_ERROR("sqatgt(%ld/%d): SCST target registration failed.",
|
||||
vha->host_no, vha->vp_idx);
|
||||
res = -ENOMEM;
|
||||
kfree(pwwn);
|
||||
kfree(sqa_tgt);
|
||||
goto done;
|
||||
}
|
||||
@@ -1491,7 +1413,6 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
scst_tgt_set_hw_dif_type3_supported(scst_tgt, true);
|
||||
}
|
||||
#endif
|
||||
kfree(pwwn);
|
||||
INIT_LIST_HEAD(&sqa_tgt->list);
|
||||
sqa_tgt->scst_tgt = scst_tgt;
|
||||
sqa_tgt->qla_tgt = vha->vha_tgt.qla_tgt;
|
||||
@@ -1525,7 +1446,8 @@ static int sqa_init_scst_tgt(struct scsi_qla_host *vha)
|
||||
TRACE(TRACE_MGMT, "sqatgt(%ld/%d): Registering target pwwn=%s "
|
||||
"scst_tgt %p sqa_tgt %p",
|
||||
vha->host_no, vha->vp_idx, pwwn, scst_tgt, sqa_tgt);
|
||||
done:
|
||||
done:
|
||||
kfree(pwwn);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1971,6 +1893,27 @@ static uint16_t sqa_get_phys_transport_version(struct scst_tgt *scst_tgt)
|
||||
return 0x0DA0;
|
||||
}
|
||||
|
||||
static int sqa_qla2xxx_chk_dif_tags(uint32_t tag)
|
||||
{
|
||||
return tag & SCST_DIF_CHECK_REF_TAG;
|
||||
}
|
||||
|
||||
static int sqa_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd,
|
||||
uint16_t *pfw_prot_opts)
|
||||
{
|
||||
struct scst_cmd *scst_cmd = cmd->scst_cmd;
|
||||
uint32_t t32=0;
|
||||
|
||||
t32 = scst_get_dif_checks(scst_cmd->cmd_dif_actions);
|
||||
if (!(t32 & SCST_DIF_CHECK_GUARD_TAG))
|
||||
*pfw_prot_opts |= PO_DISABLE_GUARD_CHECK;
|
||||
|
||||
if (!(t32 & SCST_DIF_CHECK_APP_TAG))
|
||||
*pfw_prot_opts |= PO_DIS_APP_TAG_VALD;
|
||||
|
||||
return t32;
|
||||
}
|
||||
|
||||
static void sqa_cleanup_hw_pending_cmd(scsi_qla_host_t *vha,
|
||||
struct qla_tgt_cmd *cmd)
|
||||
{
|
||||
@@ -2047,7 +1990,31 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following structure defines the callbacks which will be executed
|
||||
* from functions in the qla_target.c file back to this interface
|
||||
* driver.
|
||||
*/
|
||||
static struct qla_tgt_func_tmpl sqa_qla2xxx_template = {
|
||||
.handle_cmd = sqa_qla2xxx_handle_cmd,
|
||||
.handle_data = sqa_qla2xxx_handle_data,
|
||||
.handle_tmr = sqa_qla2xxx_handle_tmr,
|
||||
.get_cmd = sqa_qla2xxx_get_cmd,
|
||||
.free_cmd = sqa_qla2xxx_free_cmd,
|
||||
.free_mcmd = sqa_qla2xxx_free_mcmd,
|
||||
.free_session = sqa_qla2xxx_free_session,
|
||||
.update_sess = sqa_qla2xxx_update_sess,
|
||||
.check_initiator_node_acl = sqa_qla2xxx_check_initiator_node_acl,
|
||||
.find_sess_by_s_id = sqa_qla2xxx_find_sess_by_s_id,
|
||||
.find_sess_by_loop_id = sqa_qla2xxx_find_sess_by_loop_id,
|
||||
.clear_nacl_from_fcport_map = sqa_qla2xxx_clear_nacl_from_fcport_map,
|
||||
.put_sess = sqa_qla2xxx_put_sess,
|
||||
.shutdown_sess = sqa_qla2xxx_shutdown_sess,
|
||||
.get_dif_tags = sqa_qla2xxx_dif_tags,
|
||||
.chk_dif_tags = sqa_qla2xxx_chk_dif_tags,
|
||||
.add_target = sqa_qla2xxx_add_target,
|
||||
.remove_target = sqa_qla2xxx_remove_target,
|
||||
};
|
||||
|
||||
static int sqa_lport_callback(struct scsi_qla_host *vha,
|
||||
void* target_lport_ptr, u64 npiv_wwpn, u64 npiv_wwnn)
|
||||
@@ -2311,29 +2278,6 @@ static void __exit sqa_exit(void)
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
sqa_qla2xxx_chk_dif_tags(uint32_t tag)
|
||||
{
|
||||
return tag & SCST_DIF_CHECK_REF_TAG;
|
||||
}
|
||||
|
||||
static int
|
||||
sqa_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts)
|
||||
{
|
||||
struct scst_cmd *scst_cmd = cmd->scst_cmd;
|
||||
uint32_t t32=0;
|
||||
|
||||
t32 = scst_get_dif_checks(scst_cmd->cmd_dif_actions);
|
||||
if (!(t32 & SCST_DIF_CHECK_GUARD_TAG))
|
||||
*pfw_prot_opts |= PO_DISABLE_GUARD_CHECK;
|
||||
|
||||
if (!(t32 & SCST_DIF_CHECK_APP_TAG))
|
||||
*pfw_prot_opts |= PO_DIS_APP_TAG_VALD;
|
||||
|
||||
return t32;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
module_init(sqa_init);
|
||||
module_exit(sqa_exit);
|
||||
|
||||
@@ -2393,7 +2393,6 @@ typedef struct fc_port {
|
||||
#define NVME_FLAG_RESETTING 1
|
||||
|
||||
struct fc_port *conflict;
|
||||
unsigned char logout_completed;
|
||||
int generation;
|
||||
|
||||
struct se_session *se_sess;
|
||||
@@ -2401,8 +2400,9 @@ typedef struct fc_port {
|
||||
struct qla_tgt *tgt;
|
||||
unsigned long expires;
|
||||
struct list_head del_list_entry;
|
||||
struct work_struct free_work;
|
||||
struct work_struct reg_work;
|
||||
struct work_struct post_logout_work;
|
||||
struct work_struct finish_logout_work;
|
||||
uint64_t jiffies_at_registration;
|
||||
struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
|
||||
struct completion *unreg_done;
|
||||
|
||||
@@ -224,7 +224,6 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
|
||||
goto done;
|
||||
|
||||
fcport->flags |= FCF_ASYNC_SENT;
|
||||
fcport->logout_completed = 0;
|
||||
|
||||
fcport->disc_state = DSC_LOGIN_PEND;
|
||||
sp->type = SRB_LOGIN_CMD;
|
||||
@@ -1065,7 +1064,6 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
return rval;
|
||||
|
||||
fcport->flags |= FCF_ASYNC_SENT;
|
||||
fcport->logout_completed = 0;
|
||||
|
||||
sp->type = SRB_PRLI_CMD;
|
||||
sp->name = "prli";
|
||||
@@ -4724,6 +4722,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
|
||||
|
||||
INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
|
||||
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
|
||||
INIT_WORK(&fcport->post_logout_work, qlt_post_logout);
|
||||
INIT_WORK(&fcport->finish_logout_work, qlt_finish_logout);
|
||||
INIT_LIST_HEAD(&fcport->gnl_entry);
|
||||
INIT_LIST_HEAD(&fcport->list);
|
||||
|
||||
|
||||
@@ -142,11 +142,8 @@ static void qla_nvme_sp_ls_done(void *ptr, int res)
|
||||
struct nvmefc_ls_req *fd;
|
||||
struct nvme_private *priv;
|
||||
|
||||
if (atomic_read(&sp->ref_count) == 0) {
|
||||
ql_log(ql_log_warn, sp->fcport->vha, 0x2123,
|
||||
"SP reference-count to ZERO on LS_done -- sp=%p.\n", sp);
|
||||
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!atomic_dec_and_test(&sp->ref_count))
|
||||
return;
|
||||
@@ -564,10 +561,8 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
|
||||
}
|
||||
complete(&fcport->nvme_del_done);
|
||||
|
||||
if (!test_bit(UNLOADING, &fcport->vha->dpc_flags)) {
|
||||
INIT_WORK(&fcport->free_work, qlt_free_session_done);
|
||||
schedule_work(&fcport->free_work);
|
||||
}
|
||||
if (!test_bit(UNLOADING, &fcport->vha->dpc_flags))
|
||||
schedule_work(&fcport->post_logout_work);
|
||||
|
||||
fcport->nvme_flag &= ~NVME_FLAG_DELETING;
|
||||
ql_log(ql_log_info, fcport->vha, 0x2110,
|
||||
|
||||
@@ -807,14 +807,9 @@ qla2x00_sp_compl(void *ptr, int res)
|
||||
|
||||
cmd->result = res;
|
||||
|
||||
if (atomic_read(&sp->ref_count) == 0) {
|
||||
ql_dbg(ql_dbg_io, sp->vha, 0x3015,
|
||||
"SP reference-count to ZERO -- sp=%p cmd=%p.\n",
|
||||
sp, GET_CMD_SP(sp));
|
||||
if (ql2xextended_error_logging & ql_dbg_io)
|
||||
WARN_ON(atomic_read(&sp->ref_count) == 0);
|
||||
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!atomic_dec_and_test(&sp->ref_count))
|
||||
return;
|
||||
|
||||
@@ -916,14 +911,9 @@ qla2xxx_qpair_sp_compl(void *ptr, int res)
|
||||
|
||||
cmd->result = res;
|
||||
|
||||
if (atomic_read(&sp->ref_count) == 0) {
|
||||
ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3079,
|
||||
"SP reference-count to ZERO -- sp=%p cmd=%p.\n",
|
||||
sp, GET_CMD_SP(sp));
|
||||
if (ql2xextended_error_logging & ql_dbg_io)
|
||||
WARN_ON(atomic_read(&sp->ref_count) == 0);
|
||||
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!atomic_dec_and_test(&sp->ref_count))
|
||||
return;
|
||||
|
||||
@@ -5140,8 +5130,10 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
||||
"%s %s mem alloc fail.\n",
|
||||
__func__, wwn_to_str(e->u.new_sess.port_name));
|
||||
|
||||
if (pla)
|
||||
if (pla) {
|
||||
list_del(&pla->list);
|
||||
kmem_cache_free(qla_tgt_plogi_cachep, pla);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5251,8 +5243,10 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
||||
|
||||
if (free_fcport) {
|
||||
qla2x00_free_fcport(fcport);
|
||||
if (pla)
|
||||
if (pla) {
|
||||
list_del(&pla->list);
|
||||
kmem_cache_free(qla_tgt_plogi_cachep, pla);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -692,23 +692,21 @@ done:
|
||||
void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
||||
{
|
||||
fc_port_t *t;
|
||||
unsigned long flags;
|
||||
|
||||
switch (e->u.nack.type) {
|
||||
case SRB_NACK_PRLI:
|
||||
t = e->u.nack.fcport;
|
||||
flush_work(&t->del_work);
|
||||
flush_work(&t->free_work);
|
||||
flush_work(&t->post_logout_work);
|
||||
flush_work(&t->finish_logout_work);
|
||||
mutex_lock(&vha->vha_tgt.tgt_mutex);
|
||||
t = qlt_create_sess(vha, e->u.nack.fcport, 0);
|
||||
mutex_unlock(&vha->vha_tgt.tgt_mutex);
|
||||
if (t) {
|
||||
ql_log(ql_log_info, vha, 0xd034,
|
||||
"%s create sess success %p", __func__, t);
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
/* create sess has an extra kref */
|
||||
vha->hw->tgt.tgt_ops->put_sess(e->u.nack.fcport);
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -720,9 +718,6 @@ void qla24xx_delete_sess_fn(struct work_struct *work)
|
||||
{
|
||||
fc_port_t *fcport = container_of(work, struct fc_port, del_work);
|
||||
struct qla_hw_data *ha = fcport->vha->hw;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
|
||||
if (fcport->se_sess) {
|
||||
ha->tgt.tgt_ops->shutdown_sess(fcport);
|
||||
@@ -730,7 +725,6 @@ void qla24xx_delete_sess_fn(struct work_struct *work)
|
||||
} else {
|
||||
qlt_unreg_sess(fcport);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -798,8 +792,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
vha->vp_idx, wwn_to_str(fcport->port_name), sess->loop_id);
|
||||
sess->local = 0;
|
||||
}
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -813,6 +808,8 @@ qlt_plogi_ack_find_add(struct scsi_qla_host *vha, port_id_t *id,
|
||||
{
|
||||
struct qlt_plogi_ack_t *pla;
|
||||
|
||||
lockdep_assert_held(&vha->hw->hardware_lock);
|
||||
|
||||
list_for_each_entry(pla, &vha->plogi_ack_list, list) {
|
||||
if (pla->id.b24 == id->b24) {
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x210d,
|
||||
@@ -969,16 +966,13 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
|
||||
logo->cmd_count, res);
|
||||
}
|
||||
|
||||
void qlt_free_session_done(struct work_struct *work)
|
||||
void qlt_post_logout(struct work_struct *work)
|
||||
{
|
||||
struct fc_port *sess = container_of(work, struct fc_port,
|
||||
free_work);
|
||||
struct qla_tgt *tgt = sess->tgt;
|
||||
post_logout_work);
|
||||
struct scsi_qla_host *vha = sess->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
bool logout_started = false;
|
||||
scsi_qla_host_t *base_vha;
|
||||
struct qlt_plogi_ack_t *own =
|
||||
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
|
||||
|
||||
@@ -1036,22 +1030,19 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
if (sess->se_sess != NULL)
|
||||
ha->tgt.tgt_ops->free_session(sess);
|
||||
|
||||
if (logout_started) {
|
||||
bool traced = false;
|
||||
if (!logout_started)
|
||||
qlt_finish_logout(&sess->finish_logout_work);
|
||||
}
|
||||
|
||||
while (!READ_ONCE(sess->logout_completed)) {
|
||||
if (!traced) {
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086,
|
||||
"%s: waiting for sess %p logout\n",
|
||||
__func__, sess);
|
||||
traced = true;
|
||||
}
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0xf087,
|
||||
"%s: sess %p logout completed\n", __func__, sess);
|
||||
}
|
||||
void qlt_finish_logout(struct work_struct *work)
|
||||
{
|
||||
struct fc_port *sess = container_of(work, struct fc_port,
|
||||
finish_logout_work);
|
||||
struct qla_tgt *tgt = sess->tgt;
|
||||
struct scsi_qla_host *vha = sess->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha;
|
||||
unsigned long flags;
|
||||
|
||||
if (sess->logo_ack_needed) {
|
||||
sess->logo_ack_needed = 0;
|
||||
@@ -1088,7 +1079,8 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
struct qlt_plogi_ack_t *con =
|
||||
sess->plogi_link[QLT_PLOGI_LINK_CONFLICT];
|
||||
struct imm_ntfy_from_isp *iocb;
|
||||
own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
|
||||
struct qlt_plogi_ack_t *own =
|
||||
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
|
||||
|
||||
if (con) {
|
||||
iocb = &con->iocb;
|
||||
@@ -1186,8 +1178,7 @@ void qlt_unreg_sess(struct fc_port *sess)
|
||||
sess->nvme_flag |= NVME_FLAG_DELETING;
|
||||
schedule_work(&sess->nvme_del_work);
|
||||
} else {
|
||||
INIT_WORK(&sess->free_work, qlt_free_session_done);
|
||||
schedule_work(&sess->free_work);
|
||||
schedule_work(&sess->post_logout_work);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(qlt_unreg_sess);
|
||||
@@ -1395,7 +1386,6 @@ static struct fc_port *qlt_create_sess(
|
||||
*/
|
||||
sess->logout_on_delete = 1;
|
||||
sess->keep_nport_handle = 0;
|
||||
sess->logout_completed = 0;
|
||||
|
||||
if (ha->tgt.tgt_ops->check_initiator_node_acl(vha,
|
||||
&fcport->port_name[0], sess) < 0) {
|
||||
@@ -4292,9 +4282,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
|
||||
/*
|
||||
* Drop extra session reference from qla_tgt_handle_cmd_for_atio*(
|
||||
*/
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
return;
|
||||
|
||||
out_term:
|
||||
@@ -4311,9 +4299,7 @@ out_term:
|
||||
cmd->rel_cmd(cmd);
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
static void qlt_do_work(struct work_struct *work)
|
||||
@@ -4518,9 +4504,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
|
||||
if (!cmd) {
|
||||
ql_dbg(ql_dbg_io, vha, 0x3062,
|
||||
"qla_target(%d): Allocation of cmd failed\n", vha->vp_idx);
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -4734,7 +4718,7 @@ void qlt_logo_completion_handler(fc_port_t *fcport, int rc)
|
||||
fcport->d_id.b.al_pa, rc);
|
||||
}
|
||||
|
||||
fcport->logout_completed = 1;
|
||||
schedule_work(&fcport->finish_logout_work);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4864,6 +4848,8 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
|
||||
struct qlt_plogi_ack_t *pla;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&vha->hw->hardware_lock);
|
||||
|
||||
wwn = wwn_to_u64(iocb->u.isp24.port_name);
|
||||
|
||||
port_id.b.domain = iocb->u.isp24.port_id[2];
|
||||
@@ -4947,8 +4933,10 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
|
||||
__func__, wwn_to_str(sess->port_name), sec);
|
||||
}
|
||||
|
||||
if (!conflict_sess)
|
||||
if (!conflict_sess) {
|
||||
list_del(&pla->list);
|
||||
kmem_cache_free(qla_tgt_plogi_cachep, pla);
|
||||
}
|
||||
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
goto out;
|
||||
@@ -5036,6 +5024,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
|
||||
int res = 0;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&ha->hardware_lock);
|
||||
|
||||
wwn = wwn_to_u64(iocb->u.isp24.port_name);
|
||||
|
||||
port_id.b.domain = iocb->u.isp24.port_id[2];
|
||||
@@ -5311,6 +5301,8 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
|
||||
int send_notify_ack = 1;
|
||||
uint16_t status;
|
||||
|
||||
lockdep_assert_held(&ha->hardware_lock);
|
||||
|
||||
status = le16_to_cpu(iocb->u.isp2x.status);
|
||||
switch (status) {
|
||||
case IMM_NTFY_LIP_RESET:
|
||||
@@ -6371,17 +6363,19 @@ static void qlt_abort_work(struct qla_tgt *tgt,
|
||||
}
|
||||
|
||||
rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
|
||||
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
|
||||
if (rc != 0)
|
||||
goto out_term;
|
||||
return;
|
||||
|
||||
out_term2:
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
|
||||
|
||||
if (sess)
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
|
||||
|
||||
out_term:
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
@@ -6439,9 +6433,10 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
|
||||
scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
|
||||
|
||||
rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
ha->tgt.tgt_ops->put_sess(sess);
|
||||
|
||||
if (rc != 0)
|
||||
goto out_term;
|
||||
return;
|
||||
|
||||
@@ -1069,7 +1069,9 @@ extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int);
|
||||
extern int __init qlt_init(void);
|
||||
extern void qlt_exit(void);
|
||||
extern void qlt_update_vp_map(struct scsi_qla_host *, int);
|
||||
extern void qlt_free_session_done(struct work_struct *);
|
||||
extern void qlt_post_logout(struct work_struct *);
|
||||
extern void qlt_finish_logout(struct work_struct *work);
|
||||
|
||||
/*
|
||||
* This macro is used during early initializations when host->active_mode
|
||||
* is not set. Right now, ha value is ignored.
|
||||
|
||||
@@ -679,14 +679,9 @@ qla2x00_sp_compl(void *data, void *ptr, int res)
|
||||
|
||||
cmd->result = res;
|
||||
|
||||
if (atomic_read(&sp->ref_count) == 0) {
|
||||
ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
|
||||
"SP reference-count to ZERO -- sp=%p cmd=%p.\n",
|
||||
sp, GET_CMD_SP(sp));
|
||||
if (ql2xextended_error_logging & ql_dbg_io)
|
||||
BUG();
|
||||
if (WARN_ON(atomic_read(&sp->ref_count) == 0))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!atomic_dec_and_test(&sp->ref_count))
|
||||
return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user