From: Hannes Reinecke <hare@suse.de>
Date: Tue, 25 Nov 2014 09:45:05 +0100
Subject: bfa: check for terminated commands
References: bnc#906027
Patch-Mainline: submitted to linux-scsi
The bfa driver references the scsi command directly upon completion.
However, the command itself might already been aborted by that time.
So add a check for a valid command pointer before proceeding.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/bfa/bfa_fcpim.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index d7385d1..1e120ee 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -2125,13 +2125,15 @@ static void
__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
{
struct bfa_ioim_s *ioim = cbarg;
+ struct scsi_cmnd *scmd = (struct scsi_cmnd *)ioim->dio;
if (!complete) {
bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
return;
}
- bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
+ if (scmd && scmd->host_scribble == (void *)ioim)
+ bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
}
static void
@@ -2139,6 +2141,7 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
{
struct bfa_ioim_s *ioim = cbarg;
struct bfi_ioim_rsp_s *m;
+ struct scsi_cmnd *scmd = (struct scsi_cmnd *)ioim->dio;
u8 *snsinfo = NULL;
u8 sns_len = 0;
s32 residue = 0;
@@ -2174,8 +2177,9 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
}
}
- bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
- m->scsi_status, sns_len, snsinfo, residue);
+ if (scmd && scmd->host_scribble == (void *)ioim)
+ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
+ m->scsi_status, sns_len, snsinfo, residue);
}
void
@@ -2400,20 +2404,23 @@ static void
__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
{
struct bfa_ioim_s *ioim = cbarg;
+ struct scsi_cmnd *scmd = (struct scsi_cmnd *)ioim->dio;
if (!complete) {
bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
return;
}
- bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
- 0, 0, NULL, 0);
+ if (scmd && scmd->host_scribble == (void *)ioim)
+ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio,
+ BFI_IOIM_STS_ABORTED, 0, 0, NULL, 0);
}
static void
__bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
{
struct bfa_ioim_s *ioim = cbarg;
+ struct scsi_cmnd *scmd = (struct scsi_cmnd *)ioim->dio;
bfa_stats(ioim->itnim, path_tov_expired);
if (!complete) {
@@ -2421,21 +2428,24 @@ __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
return;
}
- bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
- 0, 0, NULL, 0);
+ if (scmd && scmd->host_scribble == (void *)ioim)
+ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio,
+ BFI_IOIM_STS_PATHTOV, 0, 0, NULL, 0);
}
static void
__bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
{
struct bfa_ioim_s *ioim = cbarg;
+ struct scsi_cmnd *scmd = (struct scsi_cmnd *)ioim->dio;
if (!complete) {
bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
return;
}
- bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
+ if (scmd && scmd->host_scribble == (void *)ioim)
+ bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
}
static void
--
1.8.5.2