|
Daniel Wagner |
e481f8 |
From: Quinn Tran <qutran@marvell.com>
|
|
Daniel Wagner |
e481f8 |
Date: Tue, 12 Jul 2022 22:20:40 -0700
|
|
Daniel Wagner |
e481f8 |
Subject: scsi: qla2xxx: edif: Fix dropped IKE message
|
|
Denis Kirjanov |
718367 |
Patch-mainline: v5.20-rc1
|
|
Daniel Wagner |
e481f8 |
Git-commit: c019cd656e717349ff22d0c41d6fbfc773f48c52
|
|
Daniel Wagner |
e481f8 |
References: bsc#1201651
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
This patch fixes IKE message being dropped due to error in processing Purex
|
|
Daniel Wagner |
e481f8 |
IOCB and Continuation IOCBs.
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
Link: https://lore.kernel.org/r/20220713052045.10683-6-njavali@marvell.com
|
|
Daniel Wagner |
e481f8 |
Fixes: fac2807946c1 ("scsi: qla2xxx: edif: Add extraction of auth_els from the wire")
|
|
Daniel Wagner |
e481f8 |
Cc: stable@vger.kernel.org
|
|
Daniel Wagner |
e481f8 |
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
|
|
Daniel Wagner |
e481f8 |
Signed-off-by: Quinn Tran <qutran@marvell.com>
|
|
Daniel Wagner |
e481f8 |
Signed-off-by: Nilesh Javali <njavali@marvell.com>
|
|
Daniel Wagner |
e481f8 |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Daniel Wagner |
e481f8 |
Acked-by: Daniel Wagner <dwagner@suse.de>
|
|
Daniel Wagner |
e481f8 |
---
|
|
Daniel Wagner |
e481f8 |
drivers/scsi/qla2xxx/qla_isr.c | 54 ++++++++++++++++++-----------------------
|
|
Daniel Wagner |
e481f8 |
1 file changed, 24 insertions(+), 30 deletions(-)
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
--- a/drivers/scsi/qla2xxx/qla_isr.c
|
|
Daniel Wagner |
e481f8 |
+++ b/drivers/scsi/qla2xxx/qla_isr.c
|
|
Daniel Wagner |
e481f8 |
@@ -3720,12 +3720,11 @@ void qla24xx_nvme_ls4_iocb(struct scsi_q
|
|
Daniel Wagner |
e481f8 |
* Return: 0 all iocbs has arrived, xx- all iocbs have not arrived.
|
|
Daniel Wagner |
e481f8 |
*/
|
|
Daniel Wagner |
e481f8 |
static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
|
|
Daniel Wagner |
e481f8 |
- struct rsp_que *rsp, response_t *pkt)
|
|
Daniel Wagner |
e481f8 |
+ struct rsp_que *rsp, response_t *pkt, u32 rsp_q_in)
|
|
Daniel Wagner |
e481f8 |
{
|
|
Daniel Wagner |
e481f8 |
- int start_pkt_ring_index, end_pkt_ring_index, n_ring_index;
|
|
Daniel Wagner |
e481f8 |
- response_t *end_pkt;
|
|
Daniel Wagner |
e481f8 |
+ int start_pkt_ring_index;
|
|
Daniel Wagner |
e481f8 |
+ u32 iocb_cnt = 0;
|
|
Daniel Wagner |
e481f8 |
int rc = 0;
|
|
Daniel Wagner |
e481f8 |
- u32 rsp_q_in;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
if (pkt->entry_count == 1)
|
|
Daniel Wagner |
e481f8 |
return rc;
|
|
Daniel Wagner |
e481f8 |
@@ -3736,34 +3735,18 @@ static int qla_chk_cont_iocb_avail(struc
|
|
Daniel Wagner |
e481f8 |
else
|
|
Daniel Wagner |
e481f8 |
start_pkt_ring_index = rsp->ring_index - 1;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
- if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length)
|
|
Daniel Wagner |
e481f8 |
- end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count -
|
|
Daniel Wagner |
e481f8 |
- rsp->length - 1;
|
|
Daniel Wagner |
e481f8 |
+ if (rsp_q_in < start_pkt_ring_index)
|
|
Daniel Wagner |
e481f8 |
+ /* q in ptr is wrapped */
|
|
Daniel Wagner |
e481f8 |
+ iocb_cnt = rsp->length - start_pkt_ring_index + rsp_q_in;
|
|
Daniel Wagner |
e481f8 |
else
|
|
Daniel Wagner |
e481f8 |
- end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1;
|
|
Daniel Wagner |
e481f8 |
+ iocb_cnt = rsp_q_in - start_pkt_ring_index;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
- end_pkt = rsp->ring + end_pkt_ring_index;
|
|
Daniel Wagner |
e481f8 |
-
|
|
Daniel Wagner |
e481f8 |
- /* next pkt = end_pkt + 1 */
|
|
Daniel Wagner |
e481f8 |
- n_ring_index = end_pkt_ring_index + 1;
|
|
Daniel Wagner |
e481f8 |
- if (n_ring_index >= rsp->length)
|
|
Daniel Wagner |
e481f8 |
- n_ring_index = 0;
|
|
Daniel Wagner |
e481f8 |
-
|
|
Daniel Wagner |
e481f8 |
- rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr :
|
|
Daniel Wagner |
e481f8 |
- rd_reg_dword(rsp->rsp_q_in);
|
|
Daniel Wagner |
e481f8 |
-
|
|
Daniel Wagner |
e481f8 |
- /* rsp_q_in is either wrapped or pointing beyond endpkt */
|
|
Daniel Wagner |
e481f8 |
- if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) ||
|
|
Daniel Wagner |
e481f8 |
- rsp_q_in >= n_ring_index)
|
|
Daniel Wagner |
e481f8 |
- /* all IOCBs arrived. */
|
|
Daniel Wagner |
e481f8 |
- rc = 0;
|
|
Daniel Wagner |
e481f8 |
- else
|
|
Daniel Wagner |
e481f8 |
+ if (iocb_cnt < pkt->entry_count)
|
|
Daniel Wagner |
e481f8 |
rc = -EIO;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
- ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091,
|
|
Daniel Wagner |
e481f8 |
- "%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n",
|
|
Daniel Wagner |
e481f8 |
- __func__, rsp->ring, pkt, end_pkt, pkt->entry_count,
|
|
Daniel Wagner |
e481f8 |
- rsp_q_in, rc);
|
|
Daniel Wagner |
e481f8 |
+ ql_dbg(ql_dbg_init, vha, 0x5091,
|
|
Daniel Wagner |
e481f8 |
+ "%s - ring %p pkt %p entry count %d iocb_cnt %d rsp_q_in %d rc %d\n",
|
|
Daniel Wagner |
e481f8 |
+ __func__, rsp->ring, pkt, pkt->entry_count, iocb_cnt, rsp_q_in, rc);
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
return rc;
|
|
Daniel Wagner |
e481f8 |
}
|
|
Daniel Wagner |
e481f8 |
@@ -3780,7 +3763,7 @@ void qla24xx_process_response_queue(stru
|
|
Daniel Wagner |
e481f8 |
struct qla_hw_data *ha = vha->hw;
|
|
Daniel Wagner |
e481f8 |
struct purex_entry_24xx *purex_entry;
|
|
Daniel Wagner |
e481f8 |
struct purex_item *pure_item;
|
|
Daniel Wagner |
e481f8 |
- u16 rsp_in = 0;
|
|
Daniel Wagner |
e481f8 |
+ u16 rsp_in = 0, cur_ring_index;
|
|
Daniel Wagner |
e481f8 |
int follow_inptr, is_shadow_hba;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
if (!ha->flags.fw_started)
|
|
Daniel Wagner |
e481f8 |
@@ -3811,6 +3794,7 @@ void qla24xx_process_response_queue(stru
|
|
Daniel Wagner |
e481f8 |
(!follow_inptr &&
|
|
Daniel Wagner |
e481f8 |
rsp->ring_ptr->signature != RESPONSE_PROCESSED)) {
|
|
Daniel Wagner |
e481f8 |
pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
|
|
Daniel Wagner |
e481f8 |
+ cur_ring_index = rsp->ring_index;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
rsp->ring_index++;
|
|
Daniel Wagner |
e481f8 |
if (rsp->ring_index == rsp->length) {
|
|
Daniel Wagner |
e481f8 |
@@ -3931,7 +3915,17 @@ void qla24xx_process_response_queue(stru
|
|
Daniel Wagner |
e481f8 |
break;
|
|
Daniel Wagner |
e481f8 |
|
|
Daniel Wagner |
e481f8 |
case ELS_AUTH_ELS:
|
|
Daniel Wagner |
e481f8 |
- if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) {
|
|
Daniel Wagner |
e481f8 |
+ if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt, rsp_in)) {
|
|
Daniel Wagner |
e481f8 |
+ /*
|
|
Daniel Wagner |
e481f8 |
+ * ring_ptr and ring_index were
|
|
Daniel Wagner |
e481f8 |
+ * pre-incremented above. Reset them
|
|
Daniel Wagner |
e481f8 |
+ * back to current. Wait for next
|
|
Daniel Wagner |
e481f8 |
+ * interrupt with all IOCBs to arrive
|
|
Daniel Wagner |
e481f8 |
+ * and re-process.
|
|
Daniel Wagner |
e481f8 |
+ */
|
|
Daniel Wagner |
e481f8 |
+ rsp->ring_ptr = (response_t *)pkt;
|
|
Daniel Wagner |
e481f8 |
+ rsp->ring_index = cur_ring_index;
|
|
Daniel Wagner |
e481f8 |
+
|
|
Daniel Wagner |
e481f8 |
ql_dbg(ql_dbg_init, vha, 0x5091,
|
|
Daniel Wagner |
e481f8 |
"Defer processing ELS opcode %#x...\n",
|
|
Daniel Wagner |
e481f8 |
purex_entry->els_frame_payload[3]);
|