mirror of
https://github.com/torvalds/linux.git
synced 2024-12-31 23:31:29 +00:00
scsi: qla2xxx: edif: Flush stale events and msgs on session down
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>
This commit is contained in:
parent
b492d6a488
commit
b1af26c245
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user