Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7766b493 authored by Subhash Jadavani's avatar Subhash Jadavani Committed by Saravana Kannan
Browse files

ANDROID: GKI: scsi: add option to override the command timeout



Some platforms might be very slow and command completion may take
much longer than default scsi command timeouts.
SCSI Read/Write command timeout can be changed by blk_queue_rq_timeout()
but there is no option to override timeout for rest of the scsi commands.
This change allows the LLD to override the default scsi command timeout
for all scsi commands (except read/write).

Change-Id: Ia36c1b1ca30f86844003d7187e84bec9ed8e22a9
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
[cang@codeaurora.org: Resolved trivial merge conflicts]
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
Bug: 153569404
(cherry picked from commit 1c45bd7756bc8fabdc5c5b04e87934b563115c18)
Signed-off-by: default avatarSaravana Kannan <saravanak@google.com>
parent 0aab3881
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -279,7 +279,11 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
	rq->cmd_len = COMMAND_SIZE(cmd[0]);
	memcpy(rq->cmd, cmd, rq->cmd_len);
	rq->retries = retries;
	if (likely(!sdev->timeout_override))
		req->timeout = timeout;
	else
		req->timeout = sdev->timeout_override;

	req->cmd_flags |= flags;
	req->rq_flags |= rq_flags | RQF_QUIET;

@@ -2468,6 +2472,33 @@ void scsi_unblock_requests(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(scsi_unblock_requests);

/*
 * Function:    scsi_set_cmd_timeout_override()
 *
 * Purpose:     Utility function used by low-level drivers to override
		timeout for the scsi commands.
 *
 * Arguments:   sdev       - scsi device in question
 *		timeout	   - timeout in jiffies
 *
 * Returns:     Nothing
 *
 * Lock status: No locks are assumed held.
 *
 * Notes:	Some platforms might be very slow and command completion may
 *		take much longer than default scsi command timeouts.
 *		SCSI Read/Write command timeout can be changed by
 *		blk_queue_rq_timeout() but there is no option to override
 *		timeout for rest of the scsi commands. This function would
 *		would allow this.
 */
void scsi_set_cmd_timeout_override(struct scsi_device *sdev,
				   unsigned int timeout)
{
	sdev->timeout_override = timeout;
}
EXPORT_SYMBOL(scsi_set_cmd_timeout_override);

int __init scsi_init_queue(void)
{
	scsi_sdb_cache = kmem_cache_create("scsi_data_buffer",
+4 −1
Original line number Diff line number Diff line
@@ -967,7 +967,10 @@ static int sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
	sector >>= ilog2(sdp->sector_size) - 9;
	nr_sectors >>= ilog2(sdp->sector_size) - 9;

	if (likely(!sdp->timeout_override))
		rq->timeout = SD_WRITE_SAME_TIMEOUT;
	else
		rq->timeout = sdp->timeout_override;

	if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) {
		cmd->cmd_len = 16;
+5 −1
Original line number Diff line number Diff line
@@ -838,7 +838,11 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
	else
		at_head = 1;

	if (likely(!sdp->device->timeout_override))
		srp->rq->timeout = timeout;
	else
		srp->rq->timeout = sdp->device->timeout_override;

	kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
	blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
			      srp->rq, at_head, sg_rq_end_io);
+5 −0
Original line number Diff line number Diff line
@@ -201,6 +201,9 @@ struct scsi_device {
	unsigned unmap_limit_for_ws:1;	/* Use the UNMAP limit for WRITE SAME */
	unsigned rpm_autosuspend:1;	/* Enable runtime autosuspend at device
					 * creation time */
	/* If non-zero, use timeout (in jiffies) for all commands */
	unsigned int timeout_override;

	atomic_t disk_events_disable_depth; /* disable depth for disk events */

	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
@@ -456,6 +459,8 @@ extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);
extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);
extern int scsi_vpd_tpg_id(struct scsi_device *, int *);
extern void scsi_set_cmd_timeout_override(struct scsi_device *sdev,
					  unsigned int timeout);

#ifdef CONFIG_PM
extern int scsi_autopm_get_device(struct scsi_device *);