From: Mahesh Rajashekhara <mahesh.rajashekhara@xxxxxxxxxxxxx> Prevent kernel crash by failing outstanding I/O request when the OS takes device offline. When posted IOs to the controller's inbound queue are not picked by the controller, the driver will halt the controller and take the controller offline. When the driver takes the controller offline, the driver will fail all the outstanding requests which can sometime lead to an OS crash. Reviewed-by: Scott Benesh <scott.benesh@xxxxxxxxxxxxx> Reviewed-by: Scott Teel <scott.teel@xxxxxxxxxxxxx> Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@xxxxxxxxxxxxx> Signed-off-by: Don Brace <don.brace@xxxxxxxxxxxxx> --- drivers/scsi/smartpqi/smartpqi_init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 838274d8fadf..c9f2a3d54663 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8544,6 +8544,7 @@ static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info) unsigned int i; struct pqi_io_request *io_request; struct scsi_cmnd *scmd; + struct scsi_device *sdev; for (i = 0; i < ctrl_info->max_io_slots; i++) { io_request = &ctrl_info->io_request_pool[i]; @@ -8552,7 +8553,13 @@ static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info) scmd = io_request->scmd; if (scmd) { - set_host_byte(scmd, DID_NO_CONNECT); + sdev = scmd->device; + if (!sdev || !scsi_device_online(sdev)) { + pqi_free_io_request(io_request); + continue; + } else { + set_host_byte(scmd, DID_NO_CONNECT); + } } else { io_request->status = -ENXIO; io_request->error_info = -- 2.28.0.rc1.9.ge7ae437ac1