summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2fc
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@qlogic.com>2016-04-07 09:07:59 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-04-15 16:53:10 -0400
commitd02327a863168647b9e6fde610c4730ff4837f9e (patch)
tree14f84de3a85acbf2ee958d15effe56c764ebbc4e /drivers/scsi/bnx2fc
parentf72464d128efd22301ce58b204f3f1808013a536 (diff)
downloadlinux-d02327a863168647b9e6fde610c4730ff4837f9e.tar.gz
linux-d02327a863168647b9e6fde610c4730ff4837f9e.tar.bz2
linux-d02327a863168647b9e6fde610c4730ff4837f9e.zip
bnx2fc: Check sc_cmd device and host pointer before returning the command to the mid-layer.
When we are in connection recovery and the internal command timer on a request pops, either the scsi_cmnd->device or scsi_cmnd->device->host back pointers may be NULL as the device that the command that the request was submitted on may have been subsequently reaped due to the connection recovery. This can cause one or both of the pointers above to be NULL and cause a system crash if we try to return the command to the midlayer. Instead, double check the pointers before the return to the midlayer so as to prevent the crash and let the upper layers finish the session recovery and rediscover the device. Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 562175869d0f..026f394a3851 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -179,12 +179,24 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
bnx2fc_unmap_sg_list(io_req);
io_req->sc_cmd = NULL;
+
+ /* Sanity checks before returning command to mid-layer */
if (!sc_cmd) {
printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. "
"IO(0x%x) already cleaned up\n",
io_req->xid);
return;
}
+ if (!sc_cmd->device) {
+ pr_err(PFX "0x%x: sc_cmd->device is NULL.\n", io_req->xid);
+ return;
+ }
+ if (!sc_cmd->device->host) {
+ pr_err(PFX "0x%x: sc_cmd->device->host is NULL.\n",
+ io_req->xid);
+ return;
+ }
+
sc_cmd->result = err_code << 16;
BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n",