scsi: bnx2fc: Do not allow both a cleanup completion and abort completion for the same request

If firmware sends either cleanup or abort completion, it means other won't
be sent. Clean out flags for other as well.

Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Saurav Kashyap 2019-06-24 01:29:58 -07:00 committed by Martin K. Petersen
parent 0e0fcef972
commit 25ad7394c7
2 changed files with 33 additions and 0 deletions

View File

@ -457,6 +457,7 @@ struct bnx2fc_cmd {
#define BNX2FC_FLAG_ELS_TIMEOUT 0xb
#define BNX2FC_FLAG_CMD_LOST 0xc
#define BNX2FC_FLAG_SRR_SENT 0xd
#define BNX2FC_FLAG_ISSUE_CLEANUP_REQ 0xe
u8 rec_retry;
u8 srr_retry;
u32 srr_offset;

View File

@ -1048,6 +1048,9 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req)
/* Obtain free SQ entry */
bnx2fc_add_2_sq(tgt, xid);
/* Set flag that cleanup request is pending with the firmware */
set_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags);
/* Ring doorbell */
bnx2fc_ring_doorbell(tgt);
@ -1324,6 +1327,25 @@ void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req,
BNX2FC_IO_DBG(io_req, "Entered process_cleanup_compl "
"refcnt = %d, cmd_type = %d\n",
kref_read(&io_req->refcount), io_req->cmd_type);
/*
* Test whether there is a cleanup request pending. If not just
* exit.
*/
if (!test_and_clear_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ,
&io_req->req_flags))
return;
/*
* If we receive a cleanup completion for this request then the
* firmware will not give us an abort completion for this request
* so clear any ABTS pending flags.
*/
if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags) &&
!test_bit(BNX2FC_FLAG_ABTS_DONE, &io_req->req_flags)) {
set_bit(BNX2FC_FLAG_ABTS_DONE, &io_req->req_flags);
if (io_req->wait_for_abts_comp)
complete(&io_req->abts_done);
}
bnx2fc_scsi_done(io_req, DID_ERROR);
kref_put(&io_req->refcount, bnx2fc_cmd_release);
if (io_req->wait_for_cleanup_comp)
@ -1351,6 +1373,16 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
return;
}
/*
* If we receive an ABTS completion here then we will not receive
* a cleanup completion so clear any cleanup pending flags.
*/
if (test_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags)) {
clear_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags);
if (io_req->wait_for_cleanup_comp)
complete(&io_req->cleanup_done);
}
/* Do not issue RRQ as this IO is already cleanedup */
if (test_and_set_bit(BNX2FC_FLAG_IO_CLEANUP,
&io_req->req_flags))