pqi_scsi_done(scmd);
}
+/*
+ * Adjust the timeout value for physical devices sent to the firmware
+ * by subtracting 3 seconds for timeouts greater than or equal to 8 seconds.
+ *
+ * This provides the firmware with additional time to attempt early recovery
+ * before the OS-level timeout occurs.
+ */
+#define ADJUST_SECS_TIMEOUT_VALUE(tv) (((tv) >= 8) ? ((tv) - 3) : (tv))
+
static int pqi_raid_submit_io(struct pqi_ctrl_info *ctrl_info,
struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
struct pqi_queue_group *queue_group, bool io_high_prio)
{
int rc;
+ u32 timeout;
size_t cdb_length;
struct pqi_io_request *io_request;
struct pqi_raid_path_request *request;
+ struct request *rq;
io_request = pqi_alloc_io_request(ctrl_info, scmd);
if (!io_request)
return SCSI_MLQUEUE_HOST_BUSY;
}
+ if (device->is_physical_device) {
+ rq = scsi_cmd_to_rq(scmd);
+ timeout = rq->timeout / HZ;
+ put_unaligned_le32(ADJUST_SECS_TIMEOUT_VALUE(timeout), &request->timeout);
+ }
+
pqi_start_io(ctrl_info, queue_group, RAID_PATH, io_request);
return 0;