mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
scsi: qla2xxx: edif: Flush stale events and msgs on session down
[ Upstream commitb1af26c245] On session down, driver will flush all stale messages and doorbell events. This prevents authentication application from having to process stale data. Link: https://lore.kernel.org/r/20211026115412.27691-7-njavali@marvell.com Fixes:4de067e5df("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Co-developed-by: Karunakara Merugu <kmerugu@marvell.com> Signed-off-by: Karunakara Merugu <kmerugu@marvell.com> Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
dcd0c5e7de
commit
aac0a76cb3
@@ -1593,6 +1593,40 @@ qla_enode_stop(scsi_qla_host_t *vha)
|
||||
spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
|
||||
}
|
||||
|
||||
static void qla_enode_clear(scsi_qla_host_t *vha, port_id_t portid)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct enode *e, *tmp;
|
||||
struct purexevent *purex;
|
||||
LIST_HEAD(enode_list);
|
||||
|
||||
if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x09102,
|
||||
"%s enode not active\n", __func__);
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
|
||||
list_for_each_entry_safe(e, tmp, &vha->pur_cinfo.head, list) {
|
||||
purex = &e->u.purexinfo;
|
||||
if (purex->pur_info.pur_sid.b24 == portid.b24) {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x911d,
|
||||
"%s free ELS sid=%06x. xchg %x, nb=%xh\n",
|
||||
__func__, portid.b24,
|
||||
purex->pur_info.pur_rx_xchg_address,
|
||||
purex->pur_info.pur_bytes_rcvd);
|
||||
|
||||
list_del_init(&e->list);
|
||||
list_add_tail(&e->list, &enode_list);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(e, tmp, &enode_list, list) {
|
||||
list_del_init(&e->list);
|
||||
qla_enode_free(vha, e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate enode struct and populate buffer
|
||||
* returns: enode pointer with buffers
|
||||
@@ -1792,6 +1826,57 @@ qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
|
||||
node->ntype = N_UNDEF;
|
||||
}
|
||||
|
||||
static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct edb_node *e, *tmp;
|
||||
port_id_t sid;
|
||||
LIST_HEAD(edb_list);
|
||||
|
||||
if (vha->e_dbell.db_flags != EDB_ACTIVE) {
|
||||
/* doorbell list not enabled */
|
||||
ql_dbg(ql_dbg_edif, vha, 0x09102,
|
||||
"%s doorbell not enabled\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* grab lock so list doesn't move */
|
||||
spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
|
||||
list_for_each_entry_safe(e, tmp, &vha->e_dbell.head, list) {
|
||||
switch (e->ntype) {
|
||||
case VND_CMD_AUTH_STATE_NEEDED:
|
||||
case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
|
||||
sid = e->u.plogi_did;
|
||||
break;
|
||||
case VND_CMD_AUTH_STATE_ELS_RCVD:
|
||||
sid = e->u.els_sid;
|
||||
break;
|
||||
case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
|
||||
/* app wants to see this */
|
||||
continue;
|
||||
default:
|
||||
ql_log(ql_log_warn, vha, 0x09102,
|
||||
"%s unknown node type: %x\n", __func__, e->ntype);
|
||||
sid.b24 = 0;
|
||||
break;
|
||||
}
|
||||
if (sid.b24 == portid.b24) {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x910f,
|
||||
"%s free doorbell event : node type = %x %p\n",
|
||||
__func__, e->ntype, e);
|
||||
list_del_init(&e->list);
|
||||
list_add_tail(&e->list, &edb_list);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(e, tmp, &edb_list, list) {
|
||||
qla_edb_node_free(vha, e);
|
||||
list_del_init(&e->list);
|
||||
kfree(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* function called when app is stopping */
|
||||
|
||||
void
|
||||
@@ -2378,7 +2463,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
|
||||
ql_dbg(ql_dbg_edif, host, 0x0910c,
|
||||
"%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n",
|
||||
__func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24,
|
||||
purex->pur_info.pur_did.b24, p->rx_xchg_addr);
|
||||
purex->pur_info.pur_did.b24, purex->pur_info.pur_rx_xchg_address);
|
||||
|
||||
qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL);
|
||||
}
|
||||
@@ -3401,3 +3486,12 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
|
||||
qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
|
||||
}
|
||||
}
|
||||
|
||||
void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport)
|
||||
{
|
||||
if (!(fcport->flags & FCF_FCSP_DEVICE))
|
||||
return;
|
||||
|
||||
qla_edb_clear(vha, fcport->d_id);
|
||||
qla_enode_clear(vha, fcport->d_id);
|
||||
}
|
||||
|
||||
@@ -142,6 +142,8 @@ void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport);
|
||||
int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob);
|
||||
void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess);
|
||||
void qla_edif_clear_appdata(struct scsi_qla_host *vha,
|
||||
struct fc_port *fcport);
|
||||
const char *sc_to_str(uint16_t cmd);
|
||||
|
||||
/*
|
||||
|
||||
@@ -1003,6 +1003,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
"%s bypassing release_all_sadb\n",
|
||||
__func__);
|
||||
}
|
||||
qla_edif_clear_appdata(vha, sess);
|
||||
qla_edif_sess_down(vha, sess);
|
||||
}
|
||||
qla2x00_mark_device_lost(vha, sess, 0);
|
||||
|
||||
Reference in New Issue
Block a user