18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 1999 Eric Youngdale
48c2ecf20Sopenharmony_ci * Copyright (C) 2014 Christoph Hellwig
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  SCSI queueing library.
78c2ecf20Sopenharmony_ci *      Initial versions: Eric Youngdale (eric@andante.org).
88c2ecf20Sopenharmony_ci *                        Based upon conversations with large numbers
98c2ecf20Sopenharmony_ci *                        of people at Linux Expo.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/bio.h>
138c2ecf20Sopenharmony_ci#include <linux/bitops.h>
148c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
158c2ecf20Sopenharmony_ci#include <linux/completion.h>
168c2ecf20Sopenharmony_ci#include <linux/kernel.h>
178c2ecf20Sopenharmony_ci#include <linux/export.h>
188c2ecf20Sopenharmony_ci#include <linux/init.h>
198c2ecf20Sopenharmony_ci#include <linux/pci.h>
208c2ecf20Sopenharmony_ci#include <linux/delay.h>
218c2ecf20Sopenharmony_ci#include <linux/hardirq.h>
228c2ecf20Sopenharmony_ci#include <linux/scatterlist.h>
238c2ecf20Sopenharmony_ci#include <linux/blk-mq.h>
248c2ecf20Sopenharmony_ci#include <linux/ratelimit.h>
258c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <scsi/scsi.h>
288c2ecf20Sopenharmony_ci#include <scsi/scsi_cmnd.h>
298c2ecf20Sopenharmony_ci#include <scsi/scsi_dbg.h>
308c2ecf20Sopenharmony_ci#include <scsi/scsi_device.h>
318c2ecf20Sopenharmony_ci#include <scsi/scsi_driver.h>
328c2ecf20Sopenharmony_ci#include <scsi/scsi_eh.h>
338c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h>
348c2ecf20Sopenharmony_ci#include <scsi/scsi_transport.h> /* __scsi_init_queue() */
358c2ecf20Sopenharmony_ci#include <scsi/scsi_dh.h>
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <trace/events/scsi.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#include "scsi_debugfs.h"
408c2ecf20Sopenharmony_ci#include "scsi_priv.h"
418c2ecf20Sopenharmony_ci#include "scsi_logging.h"
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/*
448c2ecf20Sopenharmony_ci * Size of integrity metadata is usually small, 1 inline sg should
458c2ecf20Sopenharmony_ci * cover normal cases.
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_ci#ifdef CONFIG_ARCH_NO_SG_CHAIN
488c2ecf20Sopenharmony_ci#define  SCSI_INLINE_PROT_SG_CNT  0
498c2ecf20Sopenharmony_ci#define  SCSI_INLINE_SG_CNT  0
508c2ecf20Sopenharmony_ci#else
518c2ecf20Sopenharmony_ci#define  SCSI_INLINE_PROT_SG_CNT  1
528c2ecf20Sopenharmony_ci#define  SCSI_INLINE_SG_CNT  2
538c2ecf20Sopenharmony_ci#endif
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic struct kmem_cache *scsi_sense_cache;
568c2ecf20Sopenharmony_cistatic struct kmem_cache *scsi_sense_isadma_cache;
578c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(scsi_sense_cache_mutex);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic inline struct kmem_cache *
628c2ecf20Sopenharmony_ciscsi_select_sense_cache(bool unchecked_isa_dma)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	return unchecked_isa_dma ? scsi_sense_isadma_cache : scsi_sense_cache;
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic void scsi_free_sense_buffer(bool unchecked_isa_dma,
688c2ecf20Sopenharmony_ci				   unsigned char *sense_buffer)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	kmem_cache_free(scsi_select_sense_cache(unchecked_isa_dma),
718c2ecf20Sopenharmony_ci			sense_buffer);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic unsigned char *scsi_alloc_sense_buffer(bool unchecked_isa_dma,
758c2ecf20Sopenharmony_ci	gfp_t gfp_mask, int numa_node)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	return kmem_cache_alloc_node(scsi_select_sense_cache(unchecked_isa_dma),
788c2ecf20Sopenharmony_ci				     gfp_mask, numa_node);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ciint scsi_init_sense_cache(struct Scsi_Host *shost)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	struct kmem_cache *cache;
848c2ecf20Sopenharmony_ci	int ret = 0;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	mutex_lock(&scsi_sense_cache_mutex);
878c2ecf20Sopenharmony_ci	cache = scsi_select_sense_cache(shost->unchecked_isa_dma);
888c2ecf20Sopenharmony_ci	if (cache)
898c2ecf20Sopenharmony_ci		goto exit;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	if (shost->unchecked_isa_dma) {
928c2ecf20Sopenharmony_ci		scsi_sense_isadma_cache =
938c2ecf20Sopenharmony_ci			kmem_cache_create("scsi_sense_cache(DMA)",
948c2ecf20Sopenharmony_ci				SCSI_SENSE_BUFFERSIZE, 0,
958c2ecf20Sopenharmony_ci				SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA, NULL);
968c2ecf20Sopenharmony_ci		if (!scsi_sense_isadma_cache)
978c2ecf20Sopenharmony_ci			ret = -ENOMEM;
988c2ecf20Sopenharmony_ci	} else {
998c2ecf20Sopenharmony_ci		scsi_sense_cache =
1008c2ecf20Sopenharmony_ci			kmem_cache_create_usercopy("scsi_sense_cache",
1018c2ecf20Sopenharmony_ci				SCSI_SENSE_BUFFERSIZE, 0, SLAB_HWCACHE_ALIGN,
1028c2ecf20Sopenharmony_ci				0, SCSI_SENSE_BUFFERSIZE, NULL);
1038c2ecf20Sopenharmony_ci		if (!scsi_sense_cache)
1048c2ecf20Sopenharmony_ci			ret = -ENOMEM;
1058c2ecf20Sopenharmony_ci	}
1068c2ecf20Sopenharmony_ci exit:
1078c2ecf20Sopenharmony_ci	mutex_unlock(&scsi_sense_cache_mutex);
1088c2ecf20Sopenharmony_ci	return ret;
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/*
1128c2ecf20Sopenharmony_ci * When to reinvoke queueing after a resource shortage. It's 3 msecs to
1138c2ecf20Sopenharmony_ci * not change behaviour from the previous unplug mechanism, experimentation
1148c2ecf20Sopenharmony_ci * may prove this needs changing.
1158c2ecf20Sopenharmony_ci */
1168c2ecf20Sopenharmony_ci#define SCSI_QUEUE_DELAY	3
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic void
1198c2ecf20Sopenharmony_ciscsi_set_blocked(struct scsi_cmnd *cmd, int reason)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	struct Scsi_Host *host = cmd->device->host;
1228c2ecf20Sopenharmony_ci	struct scsi_device *device = cmd->device;
1238c2ecf20Sopenharmony_ci	struct scsi_target *starget = scsi_target(device);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	/*
1268c2ecf20Sopenharmony_ci	 * Set the appropriate busy bit for the device/host.
1278c2ecf20Sopenharmony_ci	 *
1288c2ecf20Sopenharmony_ci	 * If the host/device isn't busy, assume that something actually
1298c2ecf20Sopenharmony_ci	 * completed, and that we should be able to queue a command now.
1308c2ecf20Sopenharmony_ci	 *
1318c2ecf20Sopenharmony_ci	 * Note that the prior mid-layer assumption that any host could
1328c2ecf20Sopenharmony_ci	 * always queue at least one command is now broken.  The mid-layer
1338c2ecf20Sopenharmony_ci	 * will implement a user specifiable stall (see
1348c2ecf20Sopenharmony_ci	 * scsi_host.max_host_blocked and scsi_device.max_device_blocked)
1358c2ecf20Sopenharmony_ci	 * if a command is requeued with no other commands outstanding
1368c2ecf20Sopenharmony_ci	 * either for the device or for the host.
1378c2ecf20Sopenharmony_ci	 */
1388c2ecf20Sopenharmony_ci	switch (reason) {
1398c2ecf20Sopenharmony_ci	case SCSI_MLQUEUE_HOST_BUSY:
1408c2ecf20Sopenharmony_ci		atomic_set(&host->host_blocked, host->max_host_blocked);
1418c2ecf20Sopenharmony_ci		break;
1428c2ecf20Sopenharmony_ci	case SCSI_MLQUEUE_DEVICE_BUSY:
1438c2ecf20Sopenharmony_ci	case SCSI_MLQUEUE_EH_RETRY:
1448c2ecf20Sopenharmony_ci		atomic_set(&device->device_blocked,
1458c2ecf20Sopenharmony_ci			   device->max_device_blocked);
1468c2ecf20Sopenharmony_ci		break;
1478c2ecf20Sopenharmony_ci	case SCSI_MLQUEUE_TARGET_BUSY:
1488c2ecf20Sopenharmony_ci		atomic_set(&starget->target_blocked,
1498c2ecf20Sopenharmony_ci			   starget->max_target_blocked);
1508c2ecf20Sopenharmony_ci		break;
1518c2ecf20Sopenharmony_ci	}
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistatic void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
1558c2ecf20Sopenharmony_ci{
1568c2ecf20Sopenharmony_ci	if (cmd->request->rq_flags & RQF_DONTPREP) {
1578c2ecf20Sopenharmony_ci		cmd->request->rq_flags &= ~RQF_DONTPREP;
1588c2ecf20Sopenharmony_ci		scsi_mq_uninit_cmd(cmd);
1598c2ecf20Sopenharmony_ci	} else {
1608c2ecf20Sopenharmony_ci		WARN_ON_ONCE(true);
1618c2ecf20Sopenharmony_ci	}
1628c2ecf20Sopenharmony_ci	blk_mq_requeue_request(cmd->request, true);
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci/**
1668c2ecf20Sopenharmony_ci * __scsi_queue_insert - private queue insertion
1678c2ecf20Sopenharmony_ci * @cmd: The SCSI command being requeued
1688c2ecf20Sopenharmony_ci * @reason:  The reason for the requeue
1698c2ecf20Sopenharmony_ci * @unbusy: Whether the queue should be unbusied
1708c2ecf20Sopenharmony_ci *
1718c2ecf20Sopenharmony_ci * This is a private queue insertion.  The public interface
1728c2ecf20Sopenharmony_ci * scsi_queue_insert() always assumes the queue should be unbusied
1738c2ecf20Sopenharmony_ci * because it's always called before the completion.  This function is
1748c2ecf20Sopenharmony_ci * for a requeue after completion, which should only occur in this
1758c2ecf20Sopenharmony_ci * file.
1768c2ecf20Sopenharmony_ci */
1778c2ecf20Sopenharmony_cistatic void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	struct scsi_device *device = cmd->device;
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	SCSI_LOG_MLQUEUE(1, scmd_printk(KERN_INFO, cmd,
1828c2ecf20Sopenharmony_ci		"Inserting command %p into mlqueue\n", cmd));
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	scsi_set_blocked(cmd, reason);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	/*
1878c2ecf20Sopenharmony_ci	 * Decrement the counters, since these commands are no longer
1888c2ecf20Sopenharmony_ci	 * active on the host/device.
1898c2ecf20Sopenharmony_ci	 */
1908c2ecf20Sopenharmony_ci	if (unbusy)
1918c2ecf20Sopenharmony_ci		scsi_device_unbusy(device, cmd);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	/*
1948c2ecf20Sopenharmony_ci	 * Requeue this command.  It will go before all other commands
1958c2ecf20Sopenharmony_ci	 * that are already in the queue. Schedule requeue work under
1968c2ecf20Sopenharmony_ci	 * lock such that the kblockd_schedule_work() call happens
1978c2ecf20Sopenharmony_ci	 * before blk_cleanup_queue() finishes.
1988c2ecf20Sopenharmony_ci	 */
1998c2ecf20Sopenharmony_ci	cmd->result = 0;
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	blk_mq_requeue_request(cmd->request, true);
2028c2ecf20Sopenharmony_ci}
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/**
2058c2ecf20Sopenharmony_ci * scsi_queue_insert - Reinsert a command in the queue.
2068c2ecf20Sopenharmony_ci * @cmd:    command that we are adding to queue.
2078c2ecf20Sopenharmony_ci * @reason: why we are inserting command to queue.
2088c2ecf20Sopenharmony_ci *
2098c2ecf20Sopenharmony_ci * We do this for one of two cases. Either the host is busy and it cannot accept
2108c2ecf20Sopenharmony_ci * any more commands for the time being, or the device returned QUEUE_FULL and
2118c2ecf20Sopenharmony_ci * can accept no more commands.
2128c2ecf20Sopenharmony_ci *
2138c2ecf20Sopenharmony_ci * Context: This could be called either from an interrupt context or a normal
2148c2ecf20Sopenharmony_ci * process context.
2158c2ecf20Sopenharmony_ci */
2168c2ecf20Sopenharmony_civoid scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	__scsi_queue_insert(cmd, reason, true);
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci/**
2238c2ecf20Sopenharmony_ci * __scsi_execute - insert request and wait for the result
2248c2ecf20Sopenharmony_ci * @sdev:	scsi device
2258c2ecf20Sopenharmony_ci * @cmd:	scsi command
2268c2ecf20Sopenharmony_ci * @data_direction: data direction
2278c2ecf20Sopenharmony_ci * @buffer:	data buffer
2288c2ecf20Sopenharmony_ci * @bufflen:	len of buffer
2298c2ecf20Sopenharmony_ci * @sense:	optional sense buffer
2308c2ecf20Sopenharmony_ci * @sshdr:	optional decoded sense header
2318c2ecf20Sopenharmony_ci * @timeout:	request timeout in seconds
2328c2ecf20Sopenharmony_ci * @retries:	number of times to retry request
2338c2ecf20Sopenharmony_ci * @flags:	flags for ->cmd_flags
2348c2ecf20Sopenharmony_ci * @rq_flags:	flags for ->rq_flags
2358c2ecf20Sopenharmony_ci * @resid:	optional residual length
2368c2ecf20Sopenharmony_ci *
2378c2ecf20Sopenharmony_ci * Returns the scsi_cmnd result field if a command was executed, or a negative
2388c2ecf20Sopenharmony_ci * Linux error code if we didn't get that far.
2398c2ecf20Sopenharmony_ci */
2408c2ecf20Sopenharmony_ciint __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
2418c2ecf20Sopenharmony_ci		 int data_direction, void *buffer, unsigned bufflen,
2428c2ecf20Sopenharmony_ci		 unsigned char *sense, struct scsi_sense_hdr *sshdr,
2438c2ecf20Sopenharmony_ci		 int timeout, int retries, u64 flags, req_flags_t rq_flags,
2448c2ecf20Sopenharmony_ci		 int *resid)
2458c2ecf20Sopenharmony_ci{
2468c2ecf20Sopenharmony_ci	struct request *req;
2478c2ecf20Sopenharmony_ci	struct scsi_request *rq;
2488c2ecf20Sopenharmony_ci	int ret = DRIVER_ERROR << 24;
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	req = blk_get_request(sdev->request_queue,
2518c2ecf20Sopenharmony_ci			data_direction == DMA_TO_DEVICE ?
2528c2ecf20Sopenharmony_ci			REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
2538c2ecf20Sopenharmony_ci			rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
2548c2ecf20Sopenharmony_ci	if (IS_ERR(req))
2558c2ecf20Sopenharmony_ci		return ret;
2568c2ecf20Sopenharmony_ci	rq = scsi_req(req);
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	if (bufflen &&	blk_rq_map_kern(sdev->request_queue, req,
2598c2ecf20Sopenharmony_ci					buffer, bufflen, GFP_NOIO))
2608c2ecf20Sopenharmony_ci		goto out;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	rq->cmd_len = COMMAND_SIZE(cmd[0]);
2638c2ecf20Sopenharmony_ci	memcpy(rq->cmd, cmd, rq->cmd_len);
2648c2ecf20Sopenharmony_ci	rq->retries = retries;
2658c2ecf20Sopenharmony_ci	req->timeout = timeout;
2668c2ecf20Sopenharmony_ci	req->cmd_flags |= flags;
2678c2ecf20Sopenharmony_ci	req->rq_flags |= rq_flags | RQF_QUIET;
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	/*
2708c2ecf20Sopenharmony_ci	 * head injection *required* here otherwise quiesce won't work
2718c2ecf20Sopenharmony_ci	 */
2728c2ecf20Sopenharmony_ci	blk_execute_rq(req->q, NULL, req, 1);
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	/*
2758c2ecf20Sopenharmony_ci	 * Some devices (USB mass-storage in particular) may transfer
2768c2ecf20Sopenharmony_ci	 * garbage data together with a residue indicating that the data
2778c2ecf20Sopenharmony_ci	 * is invalid.  Prevent the garbage from being misinterpreted
2788c2ecf20Sopenharmony_ci	 * and prevent security leaks by zeroing out the excess data.
2798c2ecf20Sopenharmony_ci	 */
2808c2ecf20Sopenharmony_ci	if (unlikely(rq->resid_len > 0 && rq->resid_len <= bufflen))
2818c2ecf20Sopenharmony_ci		memset(buffer + (bufflen - rq->resid_len), 0, rq->resid_len);
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if (resid)
2848c2ecf20Sopenharmony_ci		*resid = rq->resid_len;
2858c2ecf20Sopenharmony_ci	if (sense && rq->sense_len)
2868c2ecf20Sopenharmony_ci		memcpy(sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
2878c2ecf20Sopenharmony_ci	if (sshdr)
2888c2ecf20Sopenharmony_ci		scsi_normalize_sense(rq->sense, rq->sense_len, sshdr);
2898c2ecf20Sopenharmony_ci	ret = rq->result;
2908c2ecf20Sopenharmony_ci out:
2918c2ecf20Sopenharmony_ci	blk_put_request(req);
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	return ret;
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__scsi_execute);
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci/*
2988c2ecf20Sopenharmony_ci * Wake up the error handler if necessary. Avoid as follows that the error
2998c2ecf20Sopenharmony_ci * handler is not woken up if host in-flight requests number ==
3008c2ecf20Sopenharmony_ci * shost->host_failed: use call_rcu() in scsi_eh_scmd_add() in combination
3018c2ecf20Sopenharmony_ci * with an RCU read lock in this function to ensure that this function in
3028c2ecf20Sopenharmony_ci * its entirety either finishes before scsi_eh_scmd_add() increases the
3038c2ecf20Sopenharmony_ci * host_failed counter or that it notices the shost state change made by
3048c2ecf20Sopenharmony_ci * scsi_eh_scmd_add().
3058c2ecf20Sopenharmony_ci */
3068c2ecf20Sopenharmony_cistatic void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
3078c2ecf20Sopenharmony_ci{
3088c2ecf20Sopenharmony_ci	unsigned long flags;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	rcu_read_lock();
3118c2ecf20Sopenharmony_ci	__clear_bit(SCMD_STATE_INFLIGHT, &cmd->state);
3128c2ecf20Sopenharmony_ci	if (unlikely(scsi_host_in_recovery(shost))) {
3138c2ecf20Sopenharmony_ci		unsigned int busy = scsi_host_busy(shost);
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci		spin_lock_irqsave(shost->host_lock, flags);
3168c2ecf20Sopenharmony_ci		if (shost->host_failed || shost->host_eh_scheduled)
3178c2ecf20Sopenharmony_ci			scsi_eh_wakeup(shost, busy);
3188c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(shost->host_lock, flags);
3198c2ecf20Sopenharmony_ci	}
3208c2ecf20Sopenharmony_ci	rcu_read_unlock();
3218c2ecf20Sopenharmony_ci}
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_civoid scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = sdev->host;
3268c2ecf20Sopenharmony_ci	struct scsi_target *starget = scsi_target(sdev);
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	scsi_dec_host_busy(shost, cmd);
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	if (starget->can_queue > 0)
3318c2ecf20Sopenharmony_ci		atomic_dec(&starget->target_busy);
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	atomic_dec(&sdev->device_busy);
3348c2ecf20Sopenharmony_ci}
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_cistatic void scsi_kick_queue(struct request_queue *q)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	blk_mq_run_hw_queues(q, false);
3398c2ecf20Sopenharmony_ci}
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci/*
3428c2ecf20Sopenharmony_ci * Called for single_lun devices on IO completion. Clear starget_sdev_user,
3438c2ecf20Sopenharmony_ci * and call blk_run_queue for all the scsi_devices on the target -
3448c2ecf20Sopenharmony_ci * including current_sdev first.
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci * Called with *no* scsi locks held.
3478c2ecf20Sopenharmony_ci */
3488c2ecf20Sopenharmony_cistatic void scsi_single_lun_run(struct scsi_device *current_sdev)
3498c2ecf20Sopenharmony_ci{
3508c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = current_sdev->host;
3518c2ecf20Sopenharmony_ci	struct scsi_device *sdev, *tmp;
3528c2ecf20Sopenharmony_ci	struct scsi_target *starget = scsi_target(current_sdev);
3538c2ecf20Sopenharmony_ci	unsigned long flags;
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
3568c2ecf20Sopenharmony_ci	starget->starget_sdev_user = NULL;
3578c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	/*
3608c2ecf20Sopenharmony_ci	 * Call blk_run_queue for all LUNs on the target, starting with
3618c2ecf20Sopenharmony_ci	 * current_sdev. We race with others (to set starget_sdev_user),
3628c2ecf20Sopenharmony_ci	 * but in most cases, we will be first. Ideally, each LU on the
3638c2ecf20Sopenharmony_ci	 * target would get some limited time or requests on the target.
3648c2ecf20Sopenharmony_ci	 */
3658c2ecf20Sopenharmony_ci	scsi_kick_queue(current_sdev->request_queue);
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
3688c2ecf20Sopenharmony_ci	if (starget->starget_sdev_user)
3698c2ecf20Sopenharmony_ci		goto out;
3708c2ecf20Sopenharmony_ci	list_for_each_entry_safe(sdev, tmp, &starget->devices,
3718c2ecf20Sopenharmony_ci			same_target_siblings) {
3728c2ecf20Sopenharmony_ci		if (sdev == current_sdev)
3738c2ecf20Sopenharmony_ci			continue;
3748c2ecf20Sopenharmony_ci		if (scsi_device_get(sdev))
3758c2ecf20Sopenharmony_ci			continue;
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(shost->host_lock, flags);
3788c2ecf20Sopenharmony_ci		scsi_kick_queue(sdev->request_queue);
3798c2ecf20Sopenharmony_ci		spin_lock_irqsave(shost->host_lock, flags);
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci		scsi_device_put(sdev);
3828c2ecf20Sopenharmony_ci	}
3838c2ecf20Sopenharmony_ci out:
3848c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
3858c2ecf20Sopenharmony_ci}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_cistatic inline bool scsi_device_is_busy(struct scsi_device *sdev)
3888c2ecf20Sopenharmony_ci{
3898c2ecf20Sopenharmony_ci	if (atomic_read(&sdev->device_busy) >= sdev->queue_depth)
3908c2ecf20Sopenharmony_ci		return true;
3918c2ecf20Sopenharmony_ci	if (atomic_read(&sdev->device_blocked) > 0)
3928c2ecf20Sopenharmony_ci		return true;
3938c2ecf20Sopenharmony_ci	return false;
3948c2ecf20Sopenharmony_ci}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistatic inline bool scsi_target_is_busy(struct scsi_target *starget)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	if (starget->can_queue > 0) {
3998c2ecf20Sopenharmony_ci		if (atomic_read(&starget->target_busy) >= starget->can_queue)
4008c2ecf20Sopenharmony_ci			return true;
4018c2ecf20Sopenharmony_ci		if (atomic_read(&starget->target_blocked) > 0)
4028c2ecf20Sopenharmony_ci			return true;
4038c2ecf20Sopenharmony_ci	}
4048c2ecf20Sopenharmony_ci	return false;
4058c2ecf20Sopenharmony_ci}
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_cistatic inline bool scsi_host_is_busy(struct Scsi_Host *shost)
4088c2ecf20Sopenharmony_ci{
4098c2ecf20Sopenharmony_ci	if (atomic_read(&shost->host_blocked) > 0)
4108c2ecf20Sopenharmony_ci		return true;
4118c2ecf20Sopenharmony_ci	if (shost->host_self_blocked)
4128c2ecf20Sopenharmony_ci		return true;
4138c2ecf20Sopenharmony_ci	return false;
4148c2ecf20Sopenharmony_ci}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_cistatic void scsi_starved_list_run(struct Scsi_Host *shost)
4178c2ecf20Sopenharmony_ci{
4188c2ecf20Sopenharmony_ci	LIST_HEAD(starved_list);
4198c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
4208c2ecf20Sopenharmony_ci	unsigned long flags;
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
4238c2ecf20Sopenharmony_ci	list_splice_init(&shost->starved_list, &starved_list);
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	while (!list_empty(&starved_list)) {
4268c2ecf20Sopenharmony_ci		struct request_queue *slq;
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci		/*
4298c2ecf20Sopenharmony_ci		 * As long as shost is accepting commands and we have
4308c2ecf20Sopenharmony_ci		 * starved queues, call blk_run_queue. scsi_request_fn
4318c2ecf20Sopenharmony_ci		 * drops the queue_lock and can add us back to the
4328c2ecf20Sopenharmony_ci		 * starved_list.
4338c2ecf20Sopenharmony_ci		 *
4348c2ecf20Sopenharmony_ci		 * host_lock protects the starved_list and starved_entry.
4358c2ecf20Sopenharmony_ci		 * scsi_request_fn must get the host_lock before checking
4368c2ecf20Sopenharmony_ci		 * or modifying starved_list or starved_entry.
4378c2ecf20Sopenharmony_ci		 */
4388c2ecf20Sopenharmony_ci		if (scsi_host_is_busy(shost))
4398c2ecf20Sopenharmony_ci			break;
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci		sdev = list_entry(starved_list.next,
4428c2ecf20Sopenharmony_ci				  struct scsi_device, starved_entry);
4438c2ecf20Sopenharmony_ci		list_del_init(&sdev->starved_entry);
4448c2ecf20Sopenharmony_ci		if (scsi_target_is_busy(scsi_target(sdev))) {
4458c2ecf20Sopenharmony_ci			list_move_tail(&sdev->starved_entry,
4468c2ecf20Sopenharmony_ci				       &shost->starved_list);
4478c2ecf20Sopenharmony_ci			continue;
4488c2ecf20Sopenharmony_ci		}
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci		/*
4518c2ecf20Sopenharmony_ci		 * Once we drop the host lock, a racing scsi_remove_device()
4528c2ecf20Sopenharmony_ci		 * call may remove the sdev from the starved list and destroy
4538c2ecf20Sopenharmony_ci		 * it and the queue.  Mitigate by taking a reference to the
4548c2ecf20Sopenharmony_ci		 * queue and never touching the sdev again after we drop the
4558c2ecf20Sopenharmony_ci		 * host lock.  Note: if __scsi_remove_device() invokes
4568c2ecf20Sopenharmony_ci		 * blk_cleanup_queue() before the queue is run from this
4578c2ecf20Sopenharmony_ci		 * function then blk_run_queue() will return immediately since
4588c2ecf20Sopenharmony_ci		 * blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING.
4598c2ecf20Sopenharmony_ci		 */
4608c2ecf20Sopenharmony_ci		slq = sdev->request_queue;
4618c2ecf20Sopenharmony_ci		if (!blk_get_queue(slq))
4628c2ecf20Sopenharmony_ci			continue;
4638c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(shost->host_lock, flags);
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci		scsi_kick_queue(slq);
4668c2ecf20Sopenharmony_ci		blk_put_queue(slq);
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci		spin_lock_irqsave(shost->host_lock, flags);
4698c2ecf20Sopenharmony_ci	}
4708c2ecf20Sopenharmony_ci	/* put any unprocessed entries back */
4718c2ecf20Sopenharmony_ci	list_splice(&starved_list, &shost->starved_list);
4728c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
4738c2ecf20Sopenharmony_ci}
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci/**
4768c2ecf20Sopenharmony_ci * scsi_run_queue - Select a proper request queue to serve next.
4778c2ecf20Sopenharmony_ci * @q:  last request's queue
4788c2ecf20Sopenharmony_ci *
4798c2ecf20Sopenharmony_ci * The previous command was completely finished, start a new one if possible.
4808c2ecf20Sopenharmony_ci */
4818c2ecf20Sopenharmony_cistatic void scsi_run_queue(struct request_queue *q)
4828c2ecf20Sopenharmony_ci{
4838c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	if (scsi_target(sdev)->single_lun)
4868c2ecf20Sopenharmony_ci		scsi_single_lun_run(sdev);
4878c2ecf20Sopenharmony_ci	if (!list_empty(&sdev->host->starved_list))
4888c2ecf20Sopenharmony_ci		scsi_starved_list_run(sdev->host);
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci	blk_mq_run_hw_queues(q, false);
4918c2ecf20Sopenharmony_ci}
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_civoid scsi_requeue_run_queue(struct work_struct *work)
4948c2ecf20Sopenharmony_ci{
4958c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
4968c2ecf20Sopenharmony_ci	struct request_queue *q;
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	sdev = container_of(work, struct scsi_device, requeue_work);
4998c2ecf20Sopenharmony_ci	q = sdev->request_queue;
5008c2ecf20Sopenharmony_ci	scsi_run_queue(q);
5018c2ecf20Sopenharmony_ci}
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_civoid scsi_run_host_queues(struct Scsi_Host *shost)
5048c2ecf20Sopenharmony_ci{
5058c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	shost_for_each_device(sdev, shost)
5088c2ecf20Sopenharmony_ci		scsi_run_queue(sdev->request_queue);
5098c2ecf20Sopenharmony_ci}
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_cistatic void scsi_uninit_cmd(struct scsi_cmnd *cmd)
5128c2ecf20Sopenharmony_ci{
5138c2ecf20Sopenharmony_ci	if (!blk_rq_is_passthrough(cmd->request)) {
5148c2ecf20Sopenharmony_ci		struct scsi_driver *drv = scsi_cmd_to_driver(cmd);
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ci		if (drv->uninit_command)
5178c2ecf20Sopenharmony_ci			drv->uninit_command(cmd);
5188c2ecf20Sopenharmony_ci	}
5198c2ecf20Sopenharmony_ci}
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_civoid scsi_free_sgtables(struct scsi_cmnd *cmd)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	if (cmd->sdb.table.nents)
5248c2ecf20Sopenharmony_ci		sg_free_table_chained(&cmd->sdb.table,
5258c2ecf20Sopenharmony_ci				SCSI_INLINE_SG_CNT);
5268c2ecf20Sopenharmony_ci	if (scsi_prot_sg_count(cmd))
5278c2ecf20Sopenharmony_ci		sg_free_table_chained(&cmd->prot_sdb->table,
5288c2ecf20Sopenharmony_ci				SCSI_INLINE_PROT_SG_CNT);
5298c2ecf20Sopenharmony_ci}
5308c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_free_sgtables);
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_cistatic void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
5338c2ecf20Sopenharmony_ci{
5348c2ecf20Sopenharmony_ci	scsi_free_sgtables(cmd);
5358c2ecf20Sopenharmony_ci	scsi_uninit_cmd(cmd);
5368c2ecf20Sopenharmony_ci}
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_cistatic void scsi_run_queue_async(struct scsi_device *sdev)
5398c2ecf20Sopenharmony_ci{
5408c2ecf20Sopenharmony_ci	if (scsi_target(sdev)->single_lun ||
5418c2ecf20Sopenharmony_ci	    !list_empty(&sdev->host->starved_list)) {
5428c2ecf20Sopenharmony_ci		kblockd_schedule_work(&sdev->requeue_work);
5438c2ecf20Sopenharmony_ci	} else {
5448c2ecf20Sopenharmony_ci		/*
5458c2ecf20Sopenharmony_ci		 * smp_mb() present in sbitmap_queue_clear() or implied in
5468c2ecf20Sopenharmony_ci		 * .end_io is for ordering writing .device_busy in
5478c2ecf20Sopenharmony_ci		 * scsi_device_unbusy() and reading sdev->restarts.
5488c2ecf20Sopenharmony_ci		 */
5498c2ecf20Sopenharmony_ci		int old = atomic_read(&sdev->restarts);
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_ci		/*
5528c2ecf20Sopenharmony_ci		 * ->restarts has to be kept as non-zero if new budget
5538c2ecf20Sopenharmony_ci		 *  contention occurs.
5548c2ecf20Sopenharmony_ci		 *
5558c2ecf20Sopenharmony_ci		 *  No need to run queue when either another re-run
5568c2ecf20Sopenharmony_ci		 *  queue wins in updating ->restarts or a new budget
5578c2ecf20Sopenharmony_ci		 *  contention occurs.
5588c2ecf20Sopenharmony_ci		 */
5598c2ecf20Sopenharmony_ci		if (old && atomic_cmpxchg(&sdev->restarts, old, 0) == old)
5608c2ecf20Sopenharmony_ci			blk_mq_run_hw_queues(sdev->request_queue, true);
5618c2ecf20Sopenharmony_ci	}
5628c2ecf20Sopenharmony_ci}
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci/* Returns false when no more bytes to process, true if there are more */
5658c2ecf20Sopenharmony_cistatic bool scsi_end_request(struct request *req, blk_status_t error,
5668c2ecf20Sopenharmony_ci		unsigned int bytes)
5678c2ecf20Sopenharmony_ci{
5688c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
5698c2ecf20Sopenharmony_ci	struct scsi_device *sdev = cmd->device;
5708c2ecf20Sopenharmony_ci	struct request_queue *q = sdev->request_queue;
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	if (blk_update_request(req, error, bytes))
5738c2ecf20Sopenharmony_ci		return true;
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_ci	if (blk_queue_add_random(q))
5768c2ecf20Sopenharmony_ci		add_disk_randomness(req->rq_disk);
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	if (!blk_rq_is_scsi(req)) {
5798c2ecf20Sopenharmony_ci		WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
5808c2ecf20Sopenharmony_ci		cmd->flags &= ~SCMD_INITIALIZED;
5818c2ecf20Sopenharmony_ci	}
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	/*
5848c2ecf20Sopenharmony_ci	 * Calling rcu_barrier() is not necessary here because the
5858c2ecf20Sopenharmony_ci	 * SCSI error handler guarantees that the function called by
5868c2ecf20Sopenharmony_ci	 * call_rcu() has been called before scsi_end_request() is
5878c2ecf20Sopenharmony_ci	 * called.
5888c2ecf20Sopenharmony_ci	 */
5898c2ecf20Sopenharmony_ci	destroy_rcu_head(&cmd->rcu);
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci	/*
5928c2ecf20Sopenharmony_ci	 * In the MQ case the command gets freed by __blk_mq_end_request,
5938c2ecf20Sopenharmony_ci	 * so we have to do all cleanup that depends on it earlier.
5948c2ecf20Sopenharmony_ci	 *
5958c2ecf20Sopenharmony_ci	 * We also can't kick the queues from irq context, so we
5968c2ecf20Sopenharmony_ci	 * will have to defer it to a workqueue.
5978c2ecf20Sopenharmony_ci	 */
5988c2ecf20Sopenharmony_ci	scsi_mq_uninit_cmd(cmd);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	/*
6018c2ecf20Sopenharmony_ci	 * queue is still alive, so grab the ref for preventing it
6028c2ecf20Sopenharmony_ci	 * from being cleaned up during running queue.
6038c2ecf20Sopenharmony_ci	 */
6048c2ecf20Sopenharmony_ci	percpu_ref_get(&q->q_usage_counter);
6058c2ecf20Sopenharmony_ci
6068c2ecf20Sopenharmony_ci	__blk_mq_end_request(req, error);
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci	scsi_run_queue_async(sdev);
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci	percpu_ref_put(&q->q_usage_counter);
6118c2ecf20Sopenharmony_ci	return false;
6128c2ecf20Sopenharmony_ci}
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci/**
6158c2ecf20Sopenharmony_ci * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t
6168c2ecf20Sopenharmony_ci * @cmd:	SCSI command
6178c2ecf20Sopenharmony_ci * @result:	scsi error code
6188c2ecf20Sopenharmony_ci *
6198c2ecf20Sopenharmony_ci * Translate a SCSI result code into a blk_status_t value. May reset the host
6208c2ecf20Sopenharmony_ci * byte of @cmd->result.
6218c2ecf20Sopenharmony_ci */
6228c2ecf20Sopenharmony_cistatic blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
6238c2ecf20Sopenharmony_ci{
6248c2ecf20Sopenharmony_ci	switch (host_byte(result)) {
6258c2ecf20Sopenharmony_ci	case DID_OK:
6268c2ecf20Sopenharmony_ci		/*
6278c2ecf20Sopenharmony_ci		 * Also check the other bytes than the status byte in result
6288c2ecf20Sopenharmony_ci		 * to handle the case when a SCSI LLD sets result to
6298c2ecf20Sopenharmony_ci		 * DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION.
6308c2ecf20Sopenharmony_ci		 */
6318c2ecf20Sopenharmony_ci		if (scsi_status_is_good(result) && (result & ~0xff) == 0)
6328c2ecf20Sopenharmony_ci			return BLK_STS_OK;
6338c2ecf20Sopenharmony_ci		return BLK_STS_IOERR;
6348c2ecf20Sopenharmony_ci	case DID_TRANSPORT_FAILFAST:
6358c2ecf20Sopenharmony_ci		return BLK_STS_TRANSPORT;
6368c2ecf20Sopenharmony_ci	case DID_TARGET_FAILURE:
6378c2ecf20Sopenharmony_ci		set_host_byte(cmd, DID_OK);
6388c2ecf20Sopenharmony_ci		return BLK_STS_TARGET;
6398c2ecf20Sopenharmony_ci	case DID_NEXUS_FAILURE:
6408c2ecf20Sopenharmony_ci		set_host_byte(cmd, DID_OK);
6418c2ecf20Sopenharmony_ci		return BLK_STS_NEXUS;
6428c2ecf20Sopenharmony_ci	case DID_ALLOC_FAILURE:
6438c2ecf20Sopenharmony_ci		set_host_byte(cmd, DID_OK);
6448c2ecf20Sopenharmony_ci		return BLK_STS_NOSPC;
6458c2ecf20Sopenharmony_ci	case DID_MEDIUM_ERROR:
6468c2ecf20Sopenharmony_ci		set_host_byte(cmd, DID_OK);
6478c2ecf20Sopenharmony_ci		return BLK_STS_MEDIUM;
6488c2ecf20Sopenharmony_ci	default:
6498c2ecf20Sopenharmony_ci		return BLK_STS_IOERR;
6508c2ecf20Sopenharmony_ci	}
6518c2ecf20Sopenharmony_ci}
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci/* Helper for scsi_io_completion() when "reprep" action required. */
6548c2ecf20Sopenharmony_cistatic void scsi_io_completion_reprep(struct scsi_cmnd *cmd,
6558c2ecf20Sopenharmony_ci				      struct request_queue *q)
6568c2ecf20Sopenharmony_ci{
6578c2ecf20Sopenharmony_ci	/* A new command will be prepared and issued. */
6588c2ecf20Sopenharmony_ci	scsi_mq_requeue_cmd(cmd);
6598c2ecf20Sopenharmony_ci}
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_cistatic bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd)
6628c2ecf20Sopenharmony_ci{
6638c2ecf20Sopenharmony_ci	struct request *req = cmd->request;
6648c2ecf20Sopenharmony_ci	unsigned long wait_for;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT)
6678c2ecf20Sopenharmony_ci		return false;
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci	wait_for = (cmd->allowed + 1) * req->timeout;
6708c2ecf20Sopenharmony_ci	if (time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
6718c2ecf20Sopenharmony_ci		scmd_printk(KERN_ERR, cmd, "timing out command, waited %lus\n",
6728c2ecf20Sopenharmony_ci			    wait_for/HZ);
6738c2ecf20Sopenharmony_ci		return true;
6748c2ecf20Sopenharmony_ci	}
6758c2ecf20Sopenharmony_ci	return false;
6768c2ecf20Sopenharmony_ci}
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci/* Helper for scsi_io_completion() when special action required. */
6798c2ecf20Sopenharmony_cistatic void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
6808c2ecf20Sopenharmony_ci{
6818c2ecf20Sopenharmony_ci	struct request_queue *q = cmd->device->request_queue;
6828c2ecf20Sopenharmony_ci	struct request *req = cmd->request;
6838c2ecf20Sopenharmony_ci	int level = 0;
6848c2ecf20Sopenharmony_ci	enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY,
6858c2ecf20Sopenharmony_ci	      ACTION_DELAYED_RETRY} action;
6868c2ecf20Sopenharmony_ci	struct scsi_sense_hdr sshdr;
6878c2ecf20Sopenharmony_ci	bool sense_valid;
6888c2ecf20Sopenharmony_ci	bool sense_current = true;      /* false implies "deferred sense" */
6898c2ecf20Sopenharmony_ci	blk_status_t blk_stat;
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
6928c2ecf20Sopenharmony_ci	if (sense_valid)
6938c2ecf20Sopenharmony_ci		sense_current = !scsi_sense_is_deferred(&sshdr);
6948c2ecf20Sopenharmony_ci
6958c2ecf20Sopenharmony_ci	blk_stat = scsi_result_to_blk_status(cmd, result);
6968c2ecf20Sopenharmony_ci
6978c2ecf20Sopenharmony_ci	if (host_byte(result) == DID_RESET) {
6988c2ecf20Sopenharmony_ci		/* Third party bus reset or reset for error recovery
6998c2ecf20Sopenharmony_ci		 * reasons.  Just retry the command and see what
7008c2ecf20Sopenharmony_ci		 * happens.
7018c2ecf20Sopenharmony_ci		 */
7028c2ecf20Sopenharmony_ci		action = ACTION_RETRY;
7038c2ecf20Sopenharmony_ci	} else if (sense_valid && sense_current) {
7048c2ecf20Sopenharmony_ci		switch (sshdr.sense_key) {
7058c2ecf20Sopenharmony_ci		case UNIT_ATTENTION:
7068c2ecf20Sopenharmony_ci			if (cmd->device->removable) {
7078c2ecf20Sopenharmony_ci				/* Detected disc change.  Set a bit
7088c2ecf20Sopenharmony_ci				 * and quietly refuse further access.
7098c2ecf20Sopenharmony_ci				 */
7108c2ecf20Sopenharmony_ci				cmd->device->changed = 1;
7118c2ecf20Sopenharmony_ci				action = ACTION_FAIL;
7128c2ecf20Sopenharmony_ci			} else {
7138c2ecf20Sopenharmony_ci				/* Must have been a power glitch, or a
7148c2ecf20Sopenharmony_ci				 * bus reset.  Could not have been a
7158c2ecf20Sopenharmony_ci				 * media change, so we just retry the
7168c2ecf20Sopenharmony_ci				 * command and see what happens.
7178c2ecf20Sopenharmony_ci				 */
7188c2ecf20Sopenharmony_ci				action = ACTION_RETRY;
7198c2ecf20Sopenharmony_ci			}
7208c2ecf20Sopenharmony_ci			break;
7218c2ecf20Sopenharmony_ci		case ILLEGAL_REQUEST:
7228c2ecf20Sopenharmony_ci			/* If we had an ILLEGAL REQUEST returned, then
7238c2ecf20Sopenharmony_ci			 * we may have performed an unsupported
7248c2ecf20Sopenharmony_ci			 * command.  The only thing this should be
7258c2ecf20Sopenharmony_ci			 * would be a ten byte read where only a six
7268c2ecf20Sopenharmony_ci			 * byte read was supported.  Also, on a system
7278c2ecf20Sopenharmony_ci			 * where READ CAPACITY failed, we may have
7288c2ecf20Sopenharmony_ci			 * read past the end of the disk.
7298c2ecf20Sopenharmony_ci			 */
7308c2ecf20Sopenharmony_ci			if ((cmd->device->use_10_for_rw &&
7318c2ecf20Sopenharmony_ci			    sshdr.asc == 0x20 && sshdr.ascq == 0x00) &&
7328c2ecf20Sopenharmony_ci			    (cmd->cmnd[0] == READ_10 ||
7338c2ecf20Sopenharmony_ci			     cmd->cmnd[0] == WRITE_10)) {
7348c2ecf20Sopenharmony_ci				/* This will issue a new 6-byte command. */
7358c2ecf20Sopenharmony_ci				cmd->device->use_10_for_rw = 0;
7368c2ecf20Sopenharmony_ci				action = ACTION_REPREP;
7378c2ecf20Sopenharmony_ci			} else if (sshdr.asc == 0x10) /* DIX */ {
7388c2ecf20Sopenharmony_ci				action = ACTION_FAIL;
7398c2ecf20Sopenharmony_ci				blk_stat = BLK_STS_PROTECTION;
7408c2ecf20Sopenharmony_ci			/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
7418c2ecf20Sopenharmony_ci			} else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
7428c2ecf20Sopenharmony_ci				action = ACTION_FAIL;
7438c2ecf20Sopenharmony_ci				blk_stat = BLK_STS_TARGET;
7448c2ecf20Sopenharmony_ci			} else
7458c2ecf20Sopenharmony_ci				action = ACTION_FAIL;
7468c2ecf20Sopenharmony_ci			break;
7478c2ecf20Sopenharmony_ci		case ABORTED_COMMAND:
7488c2ecf20Sopenharmony_ci			action = ACTION_FAIL;
7498c2ecf20Sopenharmony_ci			if (sshdr.asc == 0x10) /* DIF */
7508c2ecf20Sopenharmony_ci				blk_stat = BLK_STS_PROTECTION;
7518c2ecf20Sopenharmony_ci			break;
7528c2ecf20Sopenharmony_ci		case NOT_READY:
7538c2ecf20Sopenharmony_ci			/* If the device is in the process of becoming
7548c2ecf20Sopenharmony_ci			 * ready, or has a temporary blockage, retry.
7558c2ecf20Sopenharmony_ci			 */
7568c2ecf20Sopenharmony_ci			if (sshdr.asc == 0x04) {
7578c2ecf20Sopenharmony_ci				switch (sshdr.ascq) {
7588c2ecf20Sopenharmony_ci				case 0x01: /* becoming ready */
7598c2ecf20Sopenharmony_ci				case 0x04: /* format in progress */
7608c2ecf20Sopenharmony_ci				case 0x05: /* rebuild in progress */
7618c2ecf20Sopenharmony_ci				case 0x06: /* recalculation in progress */
7628c2ecf20Sopenharmony_ci				case 0x07: /* operation in progress */
7638c2ecf20Sopenharmony_ci				case 0x08: /* Long write in progress */
7648c2ecf20Sopenharmony_ci				case 0x09: /* self test in progress */
7658c2ecf20Sopenharmony_ci				case 0x11: /* notify (enable spinup) required */
7668c2ecf20Sopenharmony_ci				case 0x14: /* space allocation in progress */
7678c2ecf20Sopenharmony_ci				case 0x1a: /* start stop unit in progress */
7688c2ecf20Sopenharmony_ci				case 0x1b: /* sanitize in progress */
7698c2ecf20Sopenharmony_ci				case 0x1d: /* configuration in progress */
7708c2ecf20Sopenharmony_ci				case 0x24: /* depopulation in progress */
7718c2ecf20Sopenharmony_ci					action = ACTION_DELAYED_RETRY;
7728c2ecf20Sopenharmony_ci					break;
7738c2ecf20Sopenharmony_ci				default:
7748c2ecf20Sopenharmony_ci					action = ACTION_FAIL;
7758c2ecf20Sopenharmony_ci					break;
7768c2ecf20Sopenharmony_ci				}
7778c2ecf20Sopenharmony_ci			} else
7788c2ecf20Sopenharmony_ci				action = ACTION_FAIL;
7798c2ecf20Sopenharmony_ci			break;
7808c2ecf20Sopenharmony_ci		case VOLUME_OVERFLOW:
7818c2ecf20Sopenharmony_ci			/* See SSC3rXX or current. */
7828c2ecf20Sopenharmony_ci			action = ACTION_FAIL;
7838c2ecf20Sopenharmony_ci			break;
7848c2ecf20Sopenharmony_ci		case DATA_PROTECT:
7858c2ecf20Sopenharmony_ci			action = ACTION_FAIL;
7868c2ecf20Sopenharmony_ci			if ((sshdr.asc == 0x0C && sshdr.ascq == 0x12) ||
7878c2ecf20Sopenharmony_ci			    (sshdr.asc == 0x55 &&
7888c2ecf20Sopenharmony_ci			     (sshdr.ascq == 0x0E || sshdr.ascq == 0x0F))) {
7898c2ecf20Sopenharmony_ci				/* Insufficient zone resources */
7908c2ecf20Sopenharmony_ci				blk_stat = BLK_STS_ZONE_OPEN_RESOURCE;
7918c2ecf20Sopenharmony_ci			}
7928c2ecf20Sopenharmony_ci			break;
7938c2ecf20Sopenharmony_ci		default:
7948c2ecf20Sopenharmony_ci			action = ACTION_FAIL;
7958c2ecf20Sopenharmony_ci			break;
7968c2ecf20Sopenharmony_ci		}
7978c2ecf20Sopenharmony_ci	} else
7988c2ecf20Sopenharmony_ci		action = ACTION_FAIL;
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	if (action != ACTION_FAIL && scsi_cmd_runtime_exceeced(cmd))
8018c2ecf20Sopenharmony_ci		action = ACTION_FAIL;
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ci	switch (action) {
8048c2ecf20Sopenharmony_ci	case ACTION_FAIL:
8058c2ecf20Sopenharmony_ci		/* Give up and fail the remainder of the request */
8068c2ecf20Sopenharmony_ci		if (!(req->rq_flags & RQF_QUIET)) {
8078c2ecf20Sopenharmony_ci			static DEFINE_RATELIMIT_STATE(_rs,
8088c2ecf20Sopenharmony_ci					DEFAULT_RATELIMIT_INTERVAL,
8098c2ecf20Sopenharmony_ci					DEFAULT_RATELIMIT_BURST);
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci			if (unlikely(scsi_logging_level))
8128c2ecf20Sopenharmony_ci				level =
8138c2ecf20Sopenharmony_ci				     SCSI_LOG_LEVEL(SCSI_LOG_MLCOMPLETE_SHIFT,
8148c2ecf20Sopenharmony_ci						    SCSI_LOG_MLCOMPLETE_BITS);
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci			/*
8178c2ecf20Sopenharmony_ci			 * if logging is enabled the failure will be printed
8188c2ecf20Sopenharmony_ci			 * in scsi_log_completion(), so avoid duplicate messages
8198c2ecf20Sopenharmony_ci			 */
8208c2ecf20Sopenharmony_ci			if (!level && __ratelimit(&_rs)) {
8218c2ecf20Sopenharmony_ci				scsi_print_result(cmd, NULL, FAILED);
8228c2ecf20Sopenharmony_ci				if (driver_byte(result) == DRIVER_SENSE)
8238c2ecf20Sopenharmony_ci					scsi_print_sense(cmd);
8248c2ecf20Sopenharmony_ci				scsi_print_command(cmd);
8258c2ecf20Sopenharmony_ci			}
8268c2ecf20Sopenharmony_ci		}
8278c2ecf20Sopenharmony_ci		if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req)))
8288c2ecf20Sopenharmony_ci			return;
8298c2ecf20Sopenharmony_ci		fallthrough;
8308c2ecf20Sopenharmony_ci	case ACTION_REPREP:
8318c2ecf20Sopenharmony_ci		scsi_io_completion_reprep(cmd, q);
8328c2ecf20Sopenharmony_ci		break;
8338c2ecf20Sopenharmony_ci	case ACTION_RETRY:
8348c2ecf20Sopenharmony_ci		/* Retry the same command immediately */
8358c2ecf20Sopenharmony_ci		__scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY, false);
8368c2ecf20Sopenharmony_ci		break;
8378c2ecf20Sopenharmony_ci	case ACTION_DELAYED_RETRY:
8388c2ecf20Sopenharmony_ci		/* Retry the same command after a delay */
8398c2ecf20Sopenharmony_ci		__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, false);
8408c2ecf20Sopenharmony_ci		break;
8418c2ecf20Sopenharmony_ci	}
8428c2ecf20Sopenharmony_ci}
8438c2ecf20Sopenharmony_ci
8448c2ecf20Sopenharmony_ci/*
8458c2ecf20Sopenharmony_ci * Helper for scsi_io_completion() when cmd->result is non-zero. Returns a
8468c2ecf20Sopenharmony_ci * new result that may suppress further error checking. Also modifies
8478c2ecf20Sopenharmony_ci * *blk_statp in some cases.
8488c2ecf20Sopenharmony_ci */
8498c2ecf20Sopenharmony_cistatic int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
8508c2ecf20Sopenharmony_ci					blk_status_t *blk_statp)
8518c2ecf20Sopenharmony_ci{
8528c2ecf20Sopenharmony_ci	bool sense_valid;
8538c2ecf20Sopenharmony_ci	bool sense_current = true;	/* false implies "deferred sense" */
8548c2ecf20Sopenharmony_ci	struct request *req = cmd->request;
8558c2ecf20Sopenharmony_ci	struct scsi_sense_hdr sshdr;
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
8588c2ecf20Sopenharmony_ci	if (sense_valid)
8598c2ecf20Sopenharmony_ci		sense_current = !scsi_sense_is_deferred(&sshdr);
8608c2ecf20Sopenharmony_ci
8618c2ecf20Sopenharmony_ci	if (blk_rq_is_passthrough(req)) {
8628c2ecf20Sopenharmony_ci		if (sense_valid) {
8638c2ecf20Sopenharmony_ci			/*
8648c2ecf20Sopenharmony_ci			 * SG_IO wants current and deferred errors
8658c2ecf20Sopenharmony_ci			 */
8668c2ecf20Sopenharmony_ci			scsi_req(req)->sense_len =
8678c2ecf20Sopenharmony_ci				min(8 + cmd->sense_buffer[7],
8688c2ecf20Sopenharmony_ci				    SCSI_SENSE_BUFFERSIZE);
8698c2ecf20Sopenharmony_ci		}
8708c2ecf20Sopenharmony_ci		if (sense_current)
8718c2ecf20Sopenharmony_ci			*blk_statp = scsi_result_to_blk_status(cmd, result);
8728c2ecf20Sopenharmony_ci	} else if (blk_rq_bytes(req) == 0 && sense_current) {
8738c2ecf20Sopenharmony_ci		/*
8748c2ecf20Sopenharmony_ci		 * Flush commands do not transfers any data, and thus cannot use
8758c2ecf20Sopenharmony_ci		 * good_bytes != blk_rq_bytes(req) as the signal for an error.
8768c2ecf20Sopenharmony_ci		 * This sets *blk_statp explicitly for the problem case.
8778c2ecf20Sopenharmony_ci		 */
8788c2ecf20Sopenharmony_ci		*blk_statp = scsi_result_to_blk_status(cmd, result);
8798c2ecf20Sopenharmony_ci	}
8808c2ecf20Sopenharmony_ci	/*
8818c2ecf20Sopenharmony_ci	 * Recovered errors need reporting, but they're always treated as
8828c2ecf20Sopenharmony_ci	 * success, so fiddle the result code here.  For passthrough requests
8838c2ecf20Sopenharmony_ci	 * we already took a copy of the original into sreq->result which
8848c2ecf20Sopenharmony_ci	 * is what gets returned to the user
8858c2ecf20Sopenharmony_ci	 */
8868c2ecf20Sopenharmony_ci	if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) {
8878c2ecf20Sopenharmony_ci		bool do_print = true;
8888c2ecf20Sopenharmony_ci		/*
8898c2ecf20Sopenharmony_ci		 * if ATA PASS-THROUGH INFORMATION AVAILABLE [0x0, 0x1d]
8908c2ecf20Sopenharmony_ci		 * skip print since caller wants ATA registers. Only occurs
8918c2ecf20Sopenharmony_ci		 * on SCSI ATA PASS_THROUGH commands when CK_COND=1
8928c2ecf20Sopenharmony_ci		 */
8938c2ecf20Sopenharmony_ci		if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d))
8948c2ecf20Sopenharmony_ci			do_print = false;
8958c2ecf20Sopenharmony_ci		else if (req->rq_flags & RQF_QUIET)
8968c2ecf20Sopenharmony_ci			do_print = false;
8978c2ecf20Sopenharmony_ci		if (do_print)
8988c2ecf20Sopenharmony_ci			scsi_print_sense(cmd);
8998c2ecf20Sopenharmony_ci		result = 0;
9008c2ecf20Sopenharmony_ci		/* for passthrough, *blk_statp may be set */
9018c2ecf20Sopenharmony_ci		*blk_statp = BLK_STS_OK;
9028c2ecf20Sopenharmony_ci	}
9038c2ecf20Sopenharmony_ci	/*
9048c2ecf20Sopenharmony_ci	 * Another corner case: the SCSI status byte is non-zero but 'good'.
9058c2ecf20Sopenharmony_ci	 * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when
9068c2ecf20Sopenharmony_ci	 * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD
9078c2ecf20Sopenharmony_ci	 * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related
9088c2ecf20Sopenharmony_ci	 * intermediate statuses (both obsolete in SAM-4) as good.
9098c2ecf20Sopenharmony_ci	 */
9108c2ecf20Sopenharmony_ci	if (status_byte(result) && scsi_status_is_good(result)) {
9118c2ecf20Sopenharmony_ci		result = 0;
9128c2ecf20Sopenharmony_ci		*blk_statp = BLK_STS_OK;
9138c2ecf20Sopenharmony_ci	}
9148c2ecf20Sopenharmony_ci	return result;
9158c2ecf20Sopenharmony_ci}
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci/**
9188c2ecf20Sopenharmony_ci * scsi_io_completion - Completion processing for SCSI commands.
9198c2ecf20Sopenharmony_ci * @cmd:	command that is finished.
9208c2ecf20Sopenharmony_ci * @good_bytes:	number of processed bytes.
9218c2ecf20Sopenharmony_ci *
9228c2ecf20Sopenharmony_ci * We will finish off the specified number of sectors. If we are done, the
9238c2ecf20Sopenharmony_ci * command block will be released and the queue function will be goosed. If we
9248c2ecf20Sopenharmony_ci * are not done then we have to figure out what to do next:
9258c2ecf20Sopenharmony_ci *
9268c2ecf20Sopenharmony_ci *   a) We can call scsi_io_completion_reprep().  The request will be
9278c2ecf20Sopenharmony_ci *	unprepared and put back on the queue.  Then a new command will
9288c2ecf20Sopenharmony_ci *	be created for it.  This should be used if we made forward
9298c2ecf20Sopenharmony_ci *	progress, or if we want to switch from READ(10) to READ(6) for
9308c2ecf20Sopenharmony_ci *	example.
9318c2ecf20Sopenharmony_ci *
9328c2ecf20Sopenharmony_ci *   b) We can call scsi_io_completion_action().  The request will be
9338c2ecf20Sopenharmony_ci *	put back on the queue and retried using the same command as
9348c2ecf20Sopenharmony_ci *	before, possibly after a delay.
9358c2ecf20Sopenharmony_ci *
9368c2ecf20Sopenharmony_ci *   c) We can call scsi_end_request() with blk_stat other than
9378c2ecf20Sopenharmony_ci *	BLK_STS_OK, to fail the remainder of the request.
9388c2ecf20Sopenharmony_ci */
9398c2ecf20Sopenharmony_civoid scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
9408c2ecf20Sopenharmony_ci{
9418c2ecf20Sopenharmony_ci	int result = cmd->result;
9428c2ecf20Sopenharmony_ci	struct request_queue *q = cmd->device->request_queue;
9438c2ecf20Sopenharmony_ci	struct request *req = cmd->request;
9448c2ecf20Sopenharmony_ci	blk_status_t blk_stat = BLK_STS_OK;
9458c2ecf20Sopenharmony_ci
9468c2ecf20Sopenharmony_ci	if (unlikely(result))	/* a nz result may or may not be an error */
9478c2ecf20Sopenharmony_ci		result = scsi_io_completion_nz_result(cmd, result, &blk_stat);
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci	if (unlikely(blk_rq_is_passthrough(req))) {
9508c2ecf20Sopenharmony_ci		/*
9518c2ecf20Sopenharmony_ci		 * scsi_result_to_blk_status may have reset the host_byte
9528c2ecf20Sopenharmony_ci		 */
9538c2ecf20Sopenharmony_ci		scsi_req(req)->result = cmd->result;
9548c2ecf20Sopenharmony_ci	}
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci	/*
9578c2ecf20Sopenharmony_ci	 * Next deal with any sectors which we were able to correctly
9588c2ecf20Sopenharmony_ci	 * handle.
9598c2ecf20Sopenharmony_ci	 */
9608c2ecf20Sopenharmony_ci	SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, cmd,
9618c2ecf20Sopenharmony_ci		"%u sectors total, %d bytes done.\n",
9628c2ecf20Sopenharmony_ci		blk_rq_sectors(req), good_bytes));
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	/*
9658c2ecf20Sopenharmony_ci	 * Failed, zero length commands always need to drop down
9668c2ecf20Sopenharmony_ci	 * to retry code. Fast path should return in this block.
9678c2ecf20Sopenharmony_ci	 */
9688c2ecf20Sopenharmony_ci	if (likely(blk_rq_bytes(req) > 0 || blk_stat == BLK_STS_OK)) {
9698c2ecf20Sopenharmony_ci		if (likely(!scsi_end_request(req, blk_stat, good_bytes)))
9708c2ecf20Sopenharmony_ci			return; /* no bytes remaining */
9718c2ecf20Sopenharmony_ci	}
9728c2ecf20Sopenharmony_ci
9738c2ecf20Sopenharmony_ci	/* Kill remainder if no retries. */
9748c2ecf20Sopenharmony_ci	if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
9758c2ecf20Sopenharmony_ci		if (scsi_end_request(req, blk_stat, blk_rq_bytes(req)))
9768c2ecf20Sopenharmony_ci			WARN_ONCE(true,
9778c2ecf20Sopenharmony_ci			    "Bytes remaining after failed, no-retry command");
9788c2ecf20Sopenharmony_ci		return;
9798c2ecf20Sopenharmony_ci	}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	/*
9828c2ecf20Sopenharmony_ci	 * If there had been no error, but we have leftover bytes in the
9838c2ecf20Sopenharmony_ci	 * requeues just queue the command up again.
9848c2ecf20Sopenharmony_ci	 */
9858c2ecf20Sopenharmony_ci	if (likely(result == 0))
9868c2ecf20Sopenharmony_ci		scsi_io_completion_reprep(cmd, q);
9878c2ecf20Sopenharmony_ci	else
9888c2ecf20Sopenharmony_ci		scsi_io_completion_action(cmd, result);
9898c2ecf20Sopenharmony_ci}
9908c2ecf20Sopenharmony_ci
9918c2ecf20Sopenharmony_cistatic inline bool scsi_cmd_needs_dma_drain(struct scsi_device *sdev,
9928c2ecf20Sopenharmony_ci		struct request *rq)
9938c2ecf20Sopenharmony_ci{
9948c2ecf20Sopenharmony_ci	return sdev->dma_drain_len && blk_rq_is_passthrough(rq) &&
9958c2ecf20Sopenharmony_ci	       !op_is_write(req_op(rq)) &&
9968c2ecf20Sopenharmony_ci	       sdev->host->hostt->dma_need_drain(rq);
9978c2ecf20Sopenharmony_ci}
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci/**
10008c2ecf20Sopenharmony_ci * scsi_alloc_sgtables - allocate S/G tables for a command
10018c2ecf20Sopenharmony_ci * @cmd:  command descriptor we wish to initialize
10028c2ecf20Sopenharmony_ci *
10038c2ecf20Sopenharmony_ci * Returns:
10048c2ecf20Sopenharmony_ci * * BLK_STS_OK       - on success
10058c2ecf20Sopenharmony_ci * * BLK_STS_RESOURCE - if the failure is retryable
10068c2ecf20Sopenharmony_ci * * BLK_STS_IOERR    - if the failure is fatal
10078c2ecf20Sopenharmony_ci */
10088c2ecf20Sopenharmony_ciblk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd)
10098c2ecf20Sopenharmony_ci{
10108c2ecf20Sopenharmony_ci	struct scsi_device *sdev = cmd->device;
10118c2ecf20Sopenharmony_ci	struct request *rq = cmd->request;
10128c2ecf20Sopenharmony_ci	unsigned short nr_segs = blk_rq_nr_phys_segments(rq);
10138c2ecf20Sopenharmony_ci	struct scatterlist *last_sg = NULL;
10148c2ecf20Sopenharmony_ci	blk_status_t ret;
10158c2ecf20Sopenharmony_ci	bool need_drain = scsi_cmd_needs_dma_drain(sdev, rq);
10168c2ecf20Sopenharmony_ci	int count;
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(!nr_segs))
10198c2ecf20Sopenharmony_ci		return BLK_STS_IOERR;
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci	/*
10228c2ecf20Sopenharmony_ci	 * Make sure there is space for the drain.  The driver must adjust
10238c2ecf20Sopenharmony_ci	 * max_hw_segments to be prepared for this.
10248c2ecf20Sopenharmony_ci	 */
10258c2ecf20Sopenharmony_ci	if (need_drain)
10268c2ecf20Sopenharmony_ci		nr_segs++;
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	/*
10298c2ecf20Sopenharmony_ci	 * If sg table allocation fails, requeue request later.
10308c2ecf20Sopenharmony_ci	 */
10318c2ecf20Sopenharmony_ci	if (unlikely(sg_alloc_table_chained(&cmd->sdb.table, nr_segs,
10328c2ecf20Sopenharmony_ci			cmd->sdb.table.sgl, SCSI_INLINE_SG_CNT)))
10338c2ecf20Sopenharmony_ci		return BLK_STS_RESOURCE;
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci	/*
10368c2ecf20Sopenharmony_ci	 * Next, walk the list, and fill in the addresses and sizes of
10378c2ecf20Sopenharmony_ci	 * each segment.
10388c2ecf20Sopenharmony_ci	 */
10398c2ecf20Sopenharmony_ci	count = __blk_rq_map_sg(rq->q, rq, cmd->sdb.table.sgl, &last_sg);
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci	if (blk_rq_bytes(rq) & rq->q->dma_pad_mask) {
10428c2ecf20Sopenharmony_ci		unsigned int pad_len =
10438c2ecf20Sopenharmony_ci			(rq->q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1;
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ci		last_sg->length += pad_len;
10468c2ecf20Sopenharmony_ci		cmd->extra_len += pad_len;
10478c2ecf20Sopenharmony_ci	}
10488c2ecf20Sopenharmony_ci
10498c2ecf20Sopenharmony_ci	if (need_drain) {
10508c2ecf20Sopenharmony_ci		sg_unmark_end(last_sg);
10518c2ecf20Sopenharmony_ci		last_sg = sg_next(last_sg);
10528c2ecf20Sopenharmony_ci		sg_set_buf(last_sg, sdev->dma_drain_buf, sdev->dma_drain_len);
10538c2ecf20Sopenharmony_ci		sg_mark_end(last_sg);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci		cmd->extra_len += sdev->dma_drain_len;
10568c2ecf20Sopenharmony_ci		count++;
10578c2ecf20Sopenharmony_ci	}
10588c2ecf20Sopenharmony_ci
10598c2ecf20Sopenharmony_ci	BUG_ON(count > cmd->sdb.table.nents);
10608c2ecf20Sopenharmony_ci	cmd->sdb.table.nents = count;
10618c2ecf20Sopenharmony_ci	cmd->sdb.length = blk_rq_payload_bytes(rq);
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci	if (blk_integrity_rq(rq)) {
10648c2ecf20Sopenharmony_ci		struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
10658c2ecf20Sopenharmony_ci		int ivecs;
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci		if (WARN_ON_ONCE(!prot_sdb)) {
10688c2ecf20Sopenharmony_ci			/*
10698c2ecf20Sopenharmony_ci			 * This can happen if someone (e.g. multipath)
10708c2ecf20Sopenharmony_ci			 * queues a command to a device on an adapter
10718c2ecf20Sopenharmony_ci			 * that does not support DIX.
10728c2ecf20Sopenharmony_ci			 */
10738c2ecf20Sopenharmony_ci			ret = BLK_STS_IOERR;
10748c2ecf20Sopenharmony_ci			goto out_free_sgtables;
10758c2ecf20Sopenharmony_ci		}
10768c2ecf20Sopenharmony_ci
10778c2ecf20Sopenharmony_ci		ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_ci		if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
10808c2ecf20Sopenharmony_ci				prot_sdb->table.sgl,
10818c2ecf20Sopenharmony_ci				SCSI_INLINE_PROT_SG_CNT)) {
10828c2ecf20Sopenharmony_ci			ret = BLK_STS_RESOURCE;
10838c2ecf20Sopenharmony_ci			goto out_free_sgtables;
10848c2ecf20Sopenharmony_ci		}
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci		count = blk_rq_map_integrity_sg(rq->q, rq->bio,
10878c2ecf20Sopenharmony_ci						prot_sdb->table.sgl);
10888c2ecf20Sopenharmony_ci		BUG_ON(count > ivecs);
10898c2ecf20Sopenharmony_ci		BUG_ON(count > queue_max_integrity_segments(rq->q));
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_ci		cmd->prot_sdb = prot_sdb;
10928c2ecf20Sopenharmony_ci		cmd->prot_sdb->table.nents = count;
10938c2ecf20Sopenharmony_ci	}
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_ci	return BLK_STS_OK;
10968c2ecf20Sopenharmony_ciout_free_sgtables:
10978c2ecf20Sopenharmony_ci	scsi_free_sgtables(cmd);
10988c2ecf20Sopenharmony_ci	return ret;
10998c2ecf20Sopenharmony_ci}
11008c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_alloc_sgtables);
11018c2ecf20Sopenharmony_ci
11028c2ecf20Sopenharmony_ci/**
11038c2ecf20Sopenharmony_ci * scsi_initialize_rq - initialize struct scsi_cmnd partially
11048c2ecf20Sopenharmony_ci * @rq: Request associated with the SCSI command to be initialized.
11058c2ecf20Sopenharmony_ci *
11068c2ecf20Sopenharmony_ci * This function initializes the members of struct scsi_cmnd that must be
11078c2ecf20Sopenharmony_ci * initialized before request processing starts and that won't be
11088c2ecf20Sopenharmony_ci * reinitialized if a SCSI command is requeued.
11098c2ecf20Sopenharmony_ci *
11108c2ecf20Sopenharmony_ci * Called from inside blk_get_request() for pass-through requests and from
11118c2ecf20Sopenharmony_ci * inside scsi_init_command() for filesystem requests.
11128c2ecf20Sopenharmony_ci */
11138c2ecf20Sopenharmony_cistatic void scsi_initialize_rq(struct request *rq)
11148c2ecf20Sopenharmony_ci{
11158c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
11168c2ecf20Sopenharmony_ci
11178c2ecf20Sopenharmony_ci	scsi_req_init(&cmd->req);
11188c2ecf20Sopenharmony_ci	init_rcu_head(&cmd->rcu);
11198c2ecf20Sopenharmony_ci	cmd->jiffies_at_alloc = jiffies;
11208c2ecf20Sopenharmony_ci	cmd->retries = 0;
11218c2ecf20Sopenharmony_ci}
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci/*
11248c2ecf20Sopenharmony_ci * Only called when the request isn't completed by SCSI, and not freed by
11258c2ecf20Sopenharmony_ci * SCSI
11268c2ecf20Sopenharmony_ci */
11278c2ecf20Sopenharmony_cistatic void scsi_cleanup_rq(struct request *rq)
11288c2ecf20Sopenharmony_ci{
11298c2ecf20Sopenharmony_ci	if (rq->rq_flags & RQF_DONTPREP) {
11308c2ecf20Sopenharmony_ci		scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq));
11318c2ecf20Sopenharmony_ci		rq->rq_flags &= ~RQF_DONTPREP;
11328c2ecf20Sopenharmony_ci	}
11338c2ecf20Sopenharmony_ci}
11348c2ecf20Sopenharmony_ci
11358c2ecf20Sopenharmony_ci/* Called before a request is prepared. See also scsi_mq_prep_fn(). */
11368c2ecf20Sopenharmony_civoid scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd)
11378c2ecf20Sopenharmony_ci{
11388c2ecf20Sopenharmony_ci	void *buf = cmd->sense_buffer;
11398c2ecf20Sopenharmony_ci	void *prot = cmd->prot_sdb;
11408c2ecf20Sopenharmony_ci	struct request *rq = blk_mq_rq_from_pdu(cmd);
11418c2ecf20Sopenharmony_ci	unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS;
11428c2ecf20Sopenharmony_ci	unsigned long jiffies_at_alloc;
11438c2ecf20Sopenharmony_ci	int retries, to_clear;
11448c2ecf20Sopenharmony_ci	bool in_flight;
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci	if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) {
11478c2ecf20Sopenharmony_ci		flags |= SCMD_INITIALIZED;
11488c2ecf20Sopenharmony_ci		scsi_initialize_rq(rq);
11498c2ecf20Sopenharmony_ci	}
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_ci	jiffies_at_alloc = cmd->jiffies_at_alloc;
11528c2ecf20Sopenharmony_ci	retries = cmd->retries;
11538c2ecf20Sopenharmony_ci	in_flight = test_bit(SCMD_STATE_INFLIGHT, &cmd->state);
11548c2ecf20Sopenharmony_ci	/*
11558c2ecf20Sopenharmony_ci	 * Zero out the cmd, except for the embedded scsi_request. Only clear
11568c2ecf20Sopenharmony_ci	 * the driver-private command data if the LLD does not supply a
11578c2ecf20Sopenharmony_ci	 * function to initialize that data.
11588c2ecf20Sopenharmony_ci	 */
11598c2ecf20Sopenharmony_ci	to_clear = sizeof(*cmd) - sizeof(cmd->req);
11608c2ecf20Sopenharmony_ci	if (!dev->host->hostt->init_cmd_priv)
11618c2ecf20Sopenharmony_ci		to_clear += dev->host->hostt->cmd_size;
11628c2ecf20Sopenharmony_ci	memset((char *)cmd + sizeof(cmd->req), 0, to_clear);
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci	cmd->device = dev;
11658c2ecf20Sopenharmony_ci	cmd->sense_buffer = buf;
11668c2ecf20Sopenharmony_ci	cmd->prot_sdb = prot;
11678c2ecf20Sopenharmony_ci	cmd->flags = flags;
11688c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
11698c2ecf20Sopenharmony_ci	cmd->jiffies_at_alloc = jiffies_at_alloc;
11708c2ecf20Sopenharmony_ci	cmd->retries = retries;
11718c2ecf20Sopenharmony_ci	if (in_flight)
11728c2ecf20Sopenharmony_ci		__set_bit(SCMD_STATE_INFLIGHT, &cmd->state);
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ci}
11758c2ecf20Sopenharmony_ci
11768c2ecf20Sopenharmony_cistatic blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev,
11778c2ecf20Sopenharmony_ci		struct request *req)
11788c2ecf20Sopenharmony_ci{
11798c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	/*
11828c2ecf20Sopenharmony_ci	 * Passthrough requests may transfer data, in which case they must
11838c2ecf20Sopenharmony_ci	 * a bio attached to them.  Or they might contain a SCSI command
11848c2ecf20Sopenharmony_ci	 * that does not transfer data, in which case they may optionally
11858c2ecf20Sopenharmony_ci	 * submit a request without an attached bio.
11868c2ecf20Sopenharmony_ci	 */
11878c2ecf20Sopenharmony_ci	if (req->bio) {
11888c2ecf20Sopenharmony_ci		blk_status_t ret = scsi_alloc_sgtables(cmd);
11898c2ecf20Sopenharmony_ci		if (unlikely(ret != BLK_STS_OK))
11908c2ecf20Sopenharmony_ci			return ret;
11918c2ecf20Sopenharmony_ci	} else {
11928c2ecf20Sopenharmony_ci		BUG_ON(blk_rq_bytes(req));
11938c2ecf20Sopenharmony_ci
11948c2ecf20Sopenharmony_ci		memset(&cmd->sdb, 0, sizeof(cmd->sdb));
11958c2ecf20Sopenharmony_ci	}
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_ci	cmd->cmd_len = scsi_req(req)->cmd_len;
11988c2ecf20Sopenharmony_ci	cmd->cmnd = scsi_req(req)->cmd;
11998c2ecf20Sopenharmony_ci	cmd->transfersize = blk_rq_bytes(req);
12008c2ecf20Sopenharmony_ci	cmd->allowed = scsi_req(req)->retries;
12018c2ecf20Sopenharmony_ci	return BLK_STS_OK;
12028c2ecf20Sopenharmony_ci}
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_cistatic blk_status_t
12058c2ecf20Sopenharmony_ciscsi_device_state_check(struct scsi_device *sdev, struct request *req)
12068c2ecf20Sopenharmony_ci{
12078c2ecf20Sopenharmony_ci	switch (sdev->sdev_state) {
12088c2ecf20Sopenharmony_ci	case SDEV_CREATED:
12098c2ecf20Sopenharmony_ci		return BLK_STS_OK;
12108c2ecf20Sopenharmony_ci	case SDEV_OFFLINE:
12118c2ecf20Sopenharmony_ci	case SDEV_TRANSPORT_OFFLINE:
12128c2ecf20Sopenharmony_ci		/*
12138c2ecf20Sopenharmony_ci		 * If the device is offline we refuse to process any
12148c2ecf20Sopenharmony_ci		 * commands.  The device must be brought online
12158c2ecf20Sopenharmony_ci		 * before trying any recovery commands.
12168c2ecf20Sopenharmony_ci		 */
12178c2ecf20Sopenharmony_ci		if (!sdev->offline_already) {
12188c2ecf20Sopenharmony_ci			sdev->offline_already = true;
12198c2ecf20Sopenharmony_ci			sdev_printk(KERN_ERR, sdev,
12208c2ecf20Sopenharmony_ci				    "rejecting I/O to offline device\n");
12218c2ecf20Sopenharmony_ci		}
12228c2ecf20Sopenharmony_ci		return BLK_STS_IOERR;
12238c2ecf20Sopenharmony_ci	case SDEV_DEL:
12248c2ecf20Sopenharmony_ci		/*
12258c2ecf20Sopenharmony_ci		 * If the device is fully deleted, we refuse to
12268c2ecf20Sopenharmony_ci		 * process any commands as well.
12278c2ecf20Sopenharmony_ci		 */
12288c2ecf20Sopenharmony_ci		sdev_printk(KERN_ERR, sdev,
12298c2ecf20Sopenharmony_ci			    "rejecting I/O to dead device\n");
12308c2ecf20Sopenharmony_ci		return BLK_STS_IOERR;
12318c2ecf20Sopenharmony_ci	case SDEV_BLOCK:
12328c2ecf20Sopenharmony_ci	case SDEV_CREATED_BLOCK:
12338c2ecf20Sopenharmony_ci		return BLK_STS_RESOURCE;
12348c2ecf20Sopenharmony_ci	case SDEV_QUIESCE:
12358c2ecf20Sopenharmony_ci		/*
12368c2ecf20Sopenharmony_ci		 * If the device is blocked we only accept power management
12378c2ecf20Sopenharmony_ci		 * commands.
12388c2ecf20Sopenharmony_ci		 */
12398c2ecf20Sopenharmony_ci		if (req && WARN_ON_ONCE(!(req->rq_flags & RQF_PM)))
12408c2ecf20Sopenharmony_ci			return BLK_STS_RESOURCE;
12418c2ecf20Sopenharmony_ci		return BLK_STS_OK;
12428c2ecf20Sopenharmony_ci	default:
12438c2ecf20Sopenharmony_ci		/*
12448c2ecf20Sopenharmony_ci		 * For any other not fully online state we only allow
12458c2ecf20Sopenharmony_ci		 * power management commands.
12468c2ecf20Sopenharmony_ci		 */
12478c2ecf20Sopenharmony_ci		if (req && !(req->rq_flags & RQF_PM))
12488c2ecf20Sopenharmony_ci			return BLK_STS_IOERR;
12498c2ecf20Sopenharmony_ci		return BLK_STS_OK;
12508c2ecf20Sopenharmony_ci	}
12518c2ecf20Sopenharmony_ci}
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci/*
12548c2ecf20Sopenharmony_ci * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else
12558c2ecf20Sopenharmony_ci * return 0.
12568c2ecf20Sopenharmony_ci *
12578c2ecf20Sopenharmony_ci * Called with the queue_lock held.
12588c2ecf20Sopenharmony_ci */
12598c2ecf20Sopenharmony_cistatic inline int scsi_dev_queue_ready(struct request_queue *q,
12608c2ecf20Sopenharmony_ci				  struct scsi_device *sdev)
12618c2ecf20Sopenharmony_ci{
12628c2ecf20Sopenharmony_ci	unsigned int busy;
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	busy = atomic_inc_return(&sdev->device_busy) - 1;
12658c2ecf20Sopenharmony_ci	if (atomic_read(&sdev->device_blocked)) {
12668c2ecf20Sopenharmony_ci		if (busy)
12678c2ecf20Sopenharmony_ci			goto out_dec;
12688c2ecf20Sopenharmony_ci
12698c2ecf20Sopenharmony_ci		/*
12708c2ecf20Sopenharmony_ci		 * unblock after device_blocked iterates to zero
12718c2ecf20Sopenharmony_ci		 */
12728c2ecf20Sopenharmony_ci		if (atomic_dec_return(&sdev->device_blocked) > 0)
12738c2ecf20Sopenharmony_ci			goto out_dec;
12748c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3, sdev_printk(KERN_INFO, sdev,
12758c2ecf20Sopenharmony_ci				   "unblocking device at zero depth\n"));
12768c2ecf20Sopenharmony_ci	}
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ci	if (busy >= sdev->queue_depth)
12798c2ecf20Sopenharmony_ci		goto out_dec;
12808c2ecf20Sopenharmony_ci
12818c2ecf20Sopenharmony_ci	return 1;
12828c2ecf20Sopenharmony_ciout_dec:
12838c2ecf20Sopenharmony_ci	atomic_dec(&sdev->device_busy);
12848c2ecf20Sopenharmony_ci	return 0;
12858c2ecf20Sopenharmony_ci}
12868c2ecf20Sopenharmony_ci
12878c2ecf20Sopenharmony_ci/*
12888c2ecf20Sopenharmony_ci * scsi_target_queue_ready: checks if there we can send commands to target
12898c2ecf20Sopenharmony_ci * @sdev: scsi device on starget to check.
12908c2ecf20Sopenharmony_ci */
12918c2ecf20Sopenharmony_cistatic inline int scsi_target_queue_ready(struct Scsi_Host *shost,
12928c2ecf20Sopenharmony_ci					   struct scsi_device *sdev)
12938c2ecf20Sopenharmony_ci{
12948c2ecf20Sopenharmony_ci	struct scsi_target *starget = scsi_target(sdev);
12958c2ecf20Sopenharmony_ci	unsigned int busy;
12968c2ecf20Sopenharmony_ci
12978c2ecf20Sopenharmony_ci	if (starget->single_lun) {
12988c2ecf20Sopenharmony_ci		spin_lock_irq(shost->host_lock);
12998c2ecf20Sopenharmony_ci		if (starget->starget_sdev_user &&
13008c2ecf20Sopenharmony_ci		    starget->starget_sdev_user != sdev) {
13018c2ecf20Sopenharmony_ci			spin_unlock_irq(shost->host_lock);
13028c2ecf20Sopenharmony_ci			return 0;
13038c2ecf20Sopenharmony_ci		}
13048c2ecf20Sopenharmony_ci		starget->starget_sdev_user = sdev;
13058c2ecf20Sopenharmony_ci		spin_unlock_irq(shost->host_lock);
13068c2ecf20Sopenharmony_ci	}
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_ci	if (starget->can_queue <= 0)
13098c2ecf20Sopenharmony_ci		return 1;
13108c2ecf20Sopenharmony_ci
13118c2ecf20Sopenharmony_ci	busy = atomic_inc_return(&starget->target_busy) - 1;
13128c2ecf20Sopenharmony_ci	if (atomic_read(&starget->target_blocked) > 0) {
13138c2ecf20Sopenharmony_ci		if (busy)
13148c2ecf20Sopenharmony_ci			goto starved;
13158c2ecf20Sopenharmony_ci
13168c2ecf20Sopenharmony_ci		/*
13178c2ecf20Sopenharmony_ci		 * unblock after target_blocked iterates to zero
13188c2ecf20Sopenharmony_ci		 */
13198c2ecf20Sopenharmony_ci		if (atomic_dec_return(&starget->target_blocked) > 0)
13208c2ecf20Sopenharmony_ci			goto out_dec;
13218c2ecf20Sopenharmony_ci
13228c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
13238c2ecf20Sopenharmony_ci				 "unblocking target at zero depth\n"));
13248c2ecf20Sopenharmony_ci	}
13258c2ecf20Sopenharmony_ci
13268c2ecf20Sopenharmony_ci	if (busy >= starget->can_queue)
13278c2ecf20Sopenharmony_ci		goto starved;
13288c2ecf20Sopenharmony_ci
13298c2ecf20Sopenharmony_ci	return 1;
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_cistarved:
13328c2ecf20Sopenharmony_ci	spin_lock_irq(shost->host_lock);
13338c2ecf20Sopenharmony_ci	list_move_tail(&sdev->starved_entry, &shost->starved_list);
13348c2ecf20Sopenharmony_ci	spin_unlock_irq(shost->host_lock);
13358c2ecf20Sopenharmony_ciout_dec:
13368c2ecf20Sopenharmony_ci	if (starget->can_queue > 0)
13378c2ecf20Sopenharmony_ci		atomic_dec(&starget->target_busy);
13388c2ecf20Sopenharmony_ci	return 0;
13398c2ecf20Sopenharmony_ci}
13408c2ecf20Sopenharmony_ci
13418c2ecf20Sopenharmony_ci/*
13428c2ecf20Sopenharmony_ci * scsi_host_queue_ready: if we can send requests to shost, return 1 else
13438c2ecf20Sopenharmony_ci * return 0. We must end up running the queue again whenever 0 is
13448c2ecf20Sopenharmony_ci * returned, else IO can hang.
13458c2ecf20Sopenharmony_ci */
13468c2ecf20Sopenharmony_cistatic inline int scsi_host_queue_ready(struct request_queue *q,
13478c2ecf20Sopenharmony_ci				   struct Scsi_Host *shost,
13488c2ecf20Sopenharmony_ci				   struct scsi_device *sdev,
13498c2ecf20Sopenharmony_ci				   struct scsi_cmnd *cmd)
13508c2ecf20Sopenharmony_ci{
13518c2ecf20Sopenharmony_ci	if (scsi_host_in_recovery(shost))
13528c2ecf20Sopenharmony_ci		return 0;
13538c2ecf20Sopenharmony_ci
13548c2ecf20Sopenharmony_ci	if (atomic_read(&shost->host_blocked) > 0) {
13558c2ecf20Sopenharmony_ci		if (scsi_host_busy(shost) > 0)
13568c2ecf20Sopenharmony_ci			goto starved;
13578c2ecf20Sopenharmony_ci
13588c2ecf20Sopenharmony_ci		/*
13598c2ecf20Sopenharmony_ci		 * unblock after host_blocked iterates to zero
13608c2ecf20Sopenharmony_ci		 */
13618c2ecf20Sopenharmony_ci		if (atomic_dec_return(&shost->host_blocked) > 0)
13628c2ecf20Sopenharmony_ci			goto out_dec;
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3,
13658c2ecf20Sopenharmony_ci			shost_printk(KERN_INFO, shost,
13668c2ecf20Sopenharmony_ci				     "unblocking host at zero depth\n"));
13678c2ecf20Sopenharmony_ci	}
13688c2ecf20Sopenharmony_ci
13698c2ecf20Sopenharmony_ci	if (shost->host_self_blocked)
13708c2ecf20Sopenharmony_ci		goto starved;
13718c2ecf20Sopenharmony_ci
13728c2ecf20Sopenharmony_ci	/* We're OK to process the command, so we can't be starved */
13738c2ecf20Sopenharmony_ci	if (!list_empty(&sdev->starved_entry)) {
13748c2ecf20Sopenharmony_ci		spin_lock_irq(shost->host_lock);
13758c2ecf20Sopenharmony_ci		if (!list_empty(&sdev->starved_entry))
13768c2ecf20Sopenharmony_ci			list_del_init(&sdev->starved_entry);
13778c2ecf20Sopenharmony_ci		spin_unlock_irq(shost->host_lock);
13788c2ecf20Sopenharmony_ci	}
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci	__set_bit(SCMD_STATE_INFLIGHT, &cmd->state);
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci	return 1;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_cistarved:
13858c2ecf20Sopenharmony_ci	spin_lock_irq(shost->host_lock);
13868c2ecf20Sopenharmony_ci	if (list_empty(&sdev->starved_entry))
13878c2ecf20Sopenharmony_ci		list_add_tail(&sdev->starved_entry, &shost->starved_list);
13888c2ecf20Sopenharmony_ci	spin_unlock_irq(shost->host_lock);
13898c2ecf20Sopenharmony_ciout_dec:
13908c2ecf20Sopenharmony_ci	scsi_dec_host_busy(shost, cmd);
13918c2ecf20Sopenharmony_ci	return 0;
13928c2ecf20Sopenharmony_ci}
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_ci/*
13958c2ecf20Sopenharmony_ci * Busy state exporting function for request stacking drivers.
13968c2ecf20Sopenharmony_ci *
13978c2ecf20Sopenharmony_ci * For efficiency, no lock is taken to check the busy state of
13988c2ecf20Sopenharmony_ci * shost/starget/sdev, since the returned value is not guaranteed and
13998c2ecf20Sopenharmony_ci * may be changed after request stacking drivers call the function,
14008c2ecf20Sopenharmony_ci * regardless of taking lock or not.
14018c2ecf20Sopenharmony_ci *
14028c2ecf20Sopenharmony_ci * When scsi can't dispatch I/Os anymore and needs to kill I/Os scsi
14038c2ecf20Sopenharmony_ci * needs to return 'not busy'. Otherwise, request stacking drivers
14048c2ecf20Sopenharmony_ci * may hold requests forever.
14058c2ecf20Sopenharmony_ci */
14068c2ecf20Sopenharmony_cistatic bool scsi_mq_lld_busy(struct request_queue *q)
14078c2ecf20Sopenharmony_ci{
14088c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
14098c2ecf20Sopenharmony_ci	struct Scsi_Host *shost;
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	if (blk_queue_dying(q))
14128c2ecf20Sopenharmony_ci		return false;
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci	shost = sdev->host;
14158c2ecf20Sopenharmony_ci
14168c2ecf20Sopenharmony_ci	/*
14178c2ecf20Sopenharmony_ci	 * Ignore host/starget busy state.
14188c2ecf20Sopenharmony_ci	 * Since block layer does not have a concept of fairness across
14198c2ecf20Sopenharmony_ci	 * multiple queues, congestion of host/starget needs to be handled
14208c2ecf20Sopenharmony_ci	 * in SCSI layer.
14218c2ecf20Sopenharmony_ci	 */
14228c2ecf20Sopenharmony_ci	if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev))
14238c2ecf20Sopenharmony_ci		return true;
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_ci	return false;
14268c2ecf20Sopenharmony_ci}
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_cistatic void scsi_softirq_done(struct request *rq)
14298c2ecf20Sopenharmony_ci{
14308c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
14318c2ecf20Sopenharmony_ci	enum scsi_disposition disposition;
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&cmd->eh_entry);
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci	atomic_inc(&cmd->device->iodone_cnt);
14368c2ecf20Sopenharmony_ci	if (cmd->result)
14378c2ecf20Sopenharmony_ci		atomic_inc(&cmd->device->ioerr_cnt);
14388c2ecf20Sopenharmony_ci
14398c2ecf20Sopenharmony_ci	disposition = scsi_decide_disposition(cmd);
14408c2ecf20Sopenharmony_ci	if (disposition != SUCCESS && scsi_cmd_runtime_exceeced(cmd))
14418c2ecf20Sopenharmony_ci		disposition = SUCCESS;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci	scsi_log_completion(cmd, disposition);
14448c2ecf20Sopenharmony_ci
14458c2ecf20Sopenharmony_ci	switch (disposition) {
14468c2ecf20Sopenharmony_ci	case SUCCESS:
14478c2ecf20Sopenharmony_ci		scsi_finish_command(cmd);
14488c2ecf20Sopenharmony_ci		break;
14498c2ecf20Sopenharmony_ci	case NEEDS_RETRY:
14508c2ecf20Sopenharmony_ci		scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
14518c2ecf20Sopenharmony_ci		break;
14528c2ecf20Sopenharmony_ci	case ADD_TO_MLQUEUE:
14538c2ecf20Sopenharmony_ci		scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
14548c2ecf20Sopenharmony_ci		break;
14558c2ecf20Sopenharmony_ci	default:
14568c2ecf20Sopenharmony_ci		scsi_eh_scmd_add(cmd);
14578c2ecf20Sopenharmony_ci		break;
14588c2ecf20Sopenharmony_ci	}
14598c2ecf20Sopenharmony_ci}
14608c2ecf20Sopenharmony_ci
14618c2ecf20Sopenharmony_ci/**
14628c2ecf20Sopenharmony_ci * scsi_dispatch_command - Dispatch a command to the low-level driver.
14638c2ecf20Sopenharmony_ci * @cmd: command block we are dispatching.
14648c2ecf20Sopenharmony_ci *
14658c2ecf20Sopenharmony_ci * Return: nonzero return request was rejected and device's queue needs to be
14668c2ecf20Sopenharmony_ci * plugged.
14678c2ecf20Sopenharmony_ci */
14688c2ecf20Sopenharmony_cistatic int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
14698c2ecf20Sopenharmony_ci{
14708c2ecf20Sopenharmony_ci	struct Scsi_Host *host = cmd->device->host;
14718c2ecf20Sopenharmony_ci	int rtn = 0;
14728c2ecf20Sopenharmony_ci
14738c2ecf20Sopenharmony_ci	atomic_inc(&cmd->device->iorequest_cnt);
14748c2ecf20Sopenharmony_ci
14758c2ecf20Sopenharmony_ci	/* check if the device is still usable */
14768c2ecf20Sopenharmony_ci	if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
14778c2ecf20Sopenharmony_ci		/* in SDEV_DEL we error all commands. DID_NO_CONNECT
14788c2ecf20Sopenharmony_ci		 * returns an immediate error upwards, and signals
14798c2ecf20Sopenharmony_ci		 * that the device is no longer present */
14808c2ecf20Sopenharmony_ci		cmd->result = DID_NO_CONNECT << 16;
14818c2ecf20Sopenharmony_ci		goto done;
14828c2ecf20Sopenharmony_ci	}
14838c2ecf20Sopenharmony_ci
14848c2ecf20Sopenharmony_ci	/* Check to see if the scsi lld made this device blocked. */
14858c2ecf20Sopenharmony_ci	if (unlikely(scsi_device_blocked(cmd->device))) {
14868c2ecf20Sopenharmony_ci		/*
14878c2ecf20Sopenharmony_ci		 * in blocked state, the command is just put back on
14888c2ecf20Sopenharmony_ci		 * the device queue.  The suspend state has already
14898c2ecf20Sopenharmony_ci		 * blocked the queue so future requests should not
14908c2ecf20Sopenharmony_ci		 * occur until the device transitions out of the
14918c2ecf20Sopenharmony_ci		 * suspend state.
14928c2ecf20Sopenharmony_ci		 */
14938c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
14948c2ecf20Sopenharmony_ci			"queuecommand : device blocked\n"));
14958c2ecf20Sopenharmony_ci		atomic_dec(&cmd->device->iorequest_cnt);
14968c2ecf20Sopenharmony_ci		return SCSI_MLQUEUE_DEVICE_BUSY;
14978c2ecf20Sopenharmony_ci	}
14988c2ecf20Sopenharmony_ci
14998c2ecf20Sopenharmony_ci	/* Store the LUN value in cmnd, if needed. */
15008c2ecf20Sopenharmony_ci	if (cmd->device->lun_in_cdb)
15018c2ecf20Sopenharmony_ci		cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
15028c2ecf20Sopenharmony_ci			       (cmd->device->lun << 5 & 0xe0);
15038c2ecf20Sopenharmony_ci
15048c2ecf20Sopenharmony_ci	scsi_log_send(cmd);
15058c2ecf20Sopenharmony_ci
15068c2ecf20Sopenharmony_ci	/*
15078c2ecf20Sopenharmony_ci	 * Before we queue this command, check if the command
15088c2ecf20Sopenharmony_ci	 * length exceeds what the host adapter can handle.
15098c2ecf20Sopenharmony_ci	 */
15108c2ecf20Sopenharmony_ci	if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
15118c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
15128c2ecf20Sopenharmony_ci			       "queuecommand : command too long. "
15138c2ecf20Sopenharmony_ci			       "cdb_size=%d host->max_cmd_len=%d\n",
15148c2ecf20Sopenharmony_ci			       cmd->cmd_len, cmd->device->host->max_cmd_len));
15158c2ecf20Sopenharmony_ci		cmd->result = (DID_ABORT << 16);
15168c2ecf20Sopenharmony_ci		goto done;
15178c2ecf20Sopenharmony_ci	}
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	if (unlikely(host->shost_state == SHOST_DEL)) {
15208c2ecf20Sopenharmony_ci		cmd->result = (DID_NO_CONNECT << 16);
15218c2ecf20Sopenharmony_ci		goto done;
15228c2ecf20Sopenharmony_ci
15238c2ecf20Sopenharmony_ci	}
15248c2ecf20Sopenharmony_ci
15258c2ecf20Sopenharmony_ci	trace_scsi_dispatch_cmd_start(cmd);
15268c2ecf20Sopenharmony_ci	rtn = host->hostt->queuecommand(host, cmd);
15278c2ecf20Sopenharmony_ci	if (rtn) {
15288c2ecf20Sopenharmony_ci		atomic_dec(&cmd->device->iorequest_cnt);
15298c2ecf20Sopenharmony_ci		trace_scsi_dispatch_cmd_error(cmd, rtn);
15308c2ecf20Sopenharmony_ci		if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
15318c2ecf20Sopenharmony_ci		    rtn != SCSI_MLQUEUE_TARGET_BUSY)
15328c2ecf20Sopenharmony_ci			rtn = SCSI_MLQUEUE_HOST_BUSY;
15338c2ecf20Sopenharmony_ci
15348c2ecf20Sopenharmony_ci		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
15358c2ecf20Sopenharmony_ci			"queuecommand : request rejected\n"));
15368c2ecf20Sopenharmony_ci	}
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci	return rtn;
15398c2ecf20Sopenharmony_ci done:
15408c2ecf20Sopenharmony_ci	cmd->scsi_done(cmd);
15418c2ecf20Sopenharmony_ci	return 0;
15428c2ecf20Sopenharmony_ci}
15438c2ecf20Sopenharmony_ci
15448c2ecf20Sopenharmony_ci/* Size in bytes of the sg-list stored in the scsi-mq command-private data. */
15458c2ecf20Sopenharmony_cistatic unsigned int scsi_mq_inline_sgl_size(struct Scsi_Host *shost)
15468c2ecf20Sopenharmony_ci{
15478c2ecf20Sopenharmony_ci	return min_t(unsigned int, shost->sg_tablesize, SCSI_INLINE_SG_CNT) *
15488c2ecf20Sopenharmony_ci		sizeof(struct scatterlist);
15498c2ecf20Sopenharmony_ci}
15508c2ecf20Sopenharmony_ci
15518c2ecf20Sopenharmony_cistatic blk_status_t scsi_prepare_cmd(struct request *req)
15528c2ecf20Sopenharmony_ci{
15538c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
15548c2ecf20Sopenharmony_ci	struct scsi_device *sdev = req->q->queuedata;
15558c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = sdev->host;
15568c2ecf20Sopenharmony_ci	struct scatterlist *sg;
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_ci	scsi_init_command(sdev, cmd);
15598c2ecf20Sopenharmony_ci
15608c2ecf20Sopenharmony_ci	cmd->request = req;
15618c2ecf20Sopenharmony_ci	cmd->tag = req->tag;
15628c2ecf20Sopenharmony_ci	cmd->prot_op = SCSI_PROT_NORMAL;
15638c2ecf20Sopenharmony_ci	if (blk_rq_bytes(req))
15648c2ecf20Sopenharmony_ci		cmd->sc_data_direction = rq_dma_dir(req);
15658c2ecf20Sopenharmony_ci	else
15668c2ecf20Sopenharmony_ci		cmd->sc_data_direction = DMA_NONE;
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci	sg = (void *)cmd + sizeof(struct scsi_cmnd) + shost->hostt->cmd_size;
15698c2ecf20Sopenharmony_ci	cmd->sdb.table.sgl = sg;
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci	if (scsi_host_get_prot(shost)) {
15728c2ecf20Sopenharmony_ci		memset(cmd->prot_sdb, 0, sizeof(struct scsi_data_buffer));
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci		cmd->prot_sdb->table.sgl =
15758c2ecf20Sopenharmony_ci			(struct scatterlist *)(cmd->prot_sdb + 1);
15768c2ecf20Sopenharmony_ci	}
15778c2ecf20Sopenharmony_ci
15788c2ecf20Sopenharmony_ci	/*
15798c2ecf20Sopenharmony_ci	 * Special handling for passthrough commands, which don't go to the ULP
15808c2ecf20Sopenharmony_ci	 * at all:
15818c2ecf20Sopenharmony_ci	 */
15828c2ecf20Sopenharmony_ci	if (blk_rq_is_scsi(req))
15838c2ecf20Sopenharmony_ci		return scsi_setup_scsi_cmnd(sdev, req);
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	if (sdev->handler && sdev->handler->prep_fn) {
15868c2ecf20Sopenharmony_ci		blk_status_t ret = sdev->handler->prep_fn(sdev, req);
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci		if (ret != BLK_STS_OK)
15898c2ecf20Sopenharmony_ci			return ret;
15908c2ecf20Sopenharmony_ci	}
15918c2ecf20Sopenharmony_ci
15928c2ecf20Sopenharmony_ci	cmd->cmnd = scsi_req(req)->cmd = scsi_req(req)->__cmd;
15938c2ecf20Sopenharmony_ci	memset(cmd->cmnd, 0, BLK_MAX_CDB);
15948c2ecf20Sopenharmony_ci	return scsi_cmd_to_driver(cmd)->init_command(cmd);
15958c2ecf20Sopenharmony_ci}
15968c2ecf20Sopenharmony_ci
15978c2ecf20Sopenharmony_cistatic void scsi_mq_done(struct scsi_cmnd *cmd)
15988c2ecf20Sopenharmony_ci{
15998c2ecf20Sopenharmony_ci	if (unlikely(blk_should_fake_timeout(cmd->request->q)))
16008c2ecf20Sopenharmony_ci		return;
16018c2ecf20Sopenharmony_ci	if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))
16028c2ecf20Sopenharmony_ci		return;
16038c2ecf20Sopenharmony_ci	trace_scsi_dispatch_cmd_done(cmd);
16048c2ecf20Sopenharmony_ci	blk_mq_complete_request(cmd->request);
16058c2ecf20Sopenharmony_ci}
16068c2ecf20Sopenharmony_ci
16078c2ecf20Sopenharmony_cistatic void scsi_mq_put_budget(struct request_queue *q)
16088c2ecf20Sopenharmony_ci{
16098c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci	atomic_dec(&sdev->device_busy);
16128c2ecf20Sopenharmony_ci}
16138c2ecf20Sopenharmony_ci
16148c2ecf20Sopenharmony_cistatic bool scsi_mq_get_budget(struct request_queue *q)
16158c2ecf20Sopenharmony_ci{
16168c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_ci	if (scsi_dev_queue_ready(q, sdev))
16198c2ecf20Sopenharmony_ci		return true;
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_ci	atomic_inc(&sdev->restarts);
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci	/*
16248c2ecf20Sopenharmony_ci	 * Orders atomic_inc(&sdev->restarts) and atomic_read(&sdev->device_busy).
16258c2ecf20Sopenharmony_ci	 * .restarts must be incremented before .device_busy is read because the
16268c2ecf20Sopenharmony_ci	 * code in scsi_run_queue_async() depends on the order of these operations.
16278c2ecf20Sopenharmony_ci	 */
16288c2ecf20Sopenharmony_ci	smp_mb__after_atomic();
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci	/*
16318c2ecf20Sopenharmony_ci	 * If all in-flight requests originated from this LUN are completed
16328c2ecf20Sopenharmony_ci	 * before reading .device_busy, sdev->device_busy will be observed as
16338c2ecf20Sopenharmony_ci	 * zero, then blk_mq_delay_run_hw_queues() will dispatch this request
16348c2ecf20Sopenharmony_ci	 * soon. Otherwise, completion of one of these requests will observe
16358c2ecf20Sopenharmony_ci	 * the .restarts flag, and the request queue will be run for handling
16368c2ecf20Sopenharmony_ci	 * this request, see scsi_end_request().
16378c2ecf20Sopenharmony_ci	 */
16388c2ecf20Sopenharmony_ci	if (unlikely(atomic_read(&sdev->device_busy) == 0 &&
16398c2ecf20Sopenharmony_ci				!scsi_device_blocked(sdev)))
16408c2ecf20Sopenharmony_ci		blk_mq_delay_run_hw_queues(sdev->request_queue, SCSI_QUEUE_DELAY);
16418c2ecf20Sopenharmony_ci	return false;
16428c2ecf20Sopenharmony_ci}
16438c2ecf20Sopenharmony_ci
16448c2ecf20Sopenharmony_cistatic blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
16458c2ecf20Sopenharmony_ci			 const struct blk_mq_queue_data *bd)
16468c2ecf20Sopenharmony_ci{
16478c2ecf20Sopenharmony_ci	struct request *req = bd->rq;
16488c2ecf20Sopenharmony_ci	struct request_queue *q = req->q;
16498c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
16508c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = sdev->host;
16518c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
16528c2ecf20Sopenharmony_ci	blk_status_t ret;
16538c2ecf20Sopenharmony_ci	int reason;
16548c2ecf20Sopenharmony_ci
16558c2ecf20Sopenharmony_ci	/*
16568c2ecf20Sopenharmony_ci	 * If the device is not in running state we will reject some or all
16578c2ecf20Sopenharmony_ci	 * commands.
16588c2ecf20Sopenharmony_ci	 */
16598c2ecf20Sopenharmony_ci	if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {
16608c2ecf20Sopenharmony_ci		ret = scsi_device_state_check(sdev, req);
16618c2ecf20Sopenharmony_ci		if (ret != BLK_STS_OK)
16628c2ecf20Sopenharmony_ci			goto out_put_budget;
16638c2ecf20Sopenharmony_ci	}
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_ci	ret = BLK_STS_RESOURCE;
16668c2ecf20Sopenharmony_ci	if (!scsi_target_queue_ready(shost, sdev))
16678c2ecf20Sopenharmony_ci		goto out_put_budget;
16688c2ecf20Sopenharmony_ci	if (!scsi_host_queue_ready(q, shost, sdev, cmd))
16698c2ecf20Sopenharmony_ci		goto out_dec_target_busy;
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_ci	if (!(req->rq_flags & RQF_DONTPREP)) {
16728c2ecf20Sopenharmony_ci		ret = scsi_prepare_cmd(req);
16738c2ecf20Sopenharmony_ci		if (ret != BLK_STS_OK)
16748c2ecf20Sopenharmony_ci			goto out_dec_host_busy;
16758c2ecf20Sopenharmony_ci		req->rq_flags |= RQF_DONTPREP;
16768c2ecf20Sopenharmony_ci	} else {
16778c2ecf20Sopenharmony_ci		clear_bit(SCMD_STATE_COMPLETE, &cmd->state);
16788c2ecf20Sopenharmony_ci	}
16798c2ecf20Sopenharmony_ci
16808c2ecf20Sopenharmony_ci	cmd->flags &= SCMD_PRESERVED_FLAGS;
16818c2ecf20Sopenharmony_ci	if (sdev->simple_tags)
16828c2ecf20Sopenharmony_ci		cmd->flags |= SCMD_TAGGED;
16838c2ecf20Sopenharmony_ci	if (bd->last)
16848c2ecf20Sopenharmony_ci		cmd->flags |= SCMD_LAST;
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci	scsi_set_resid(cmd, 0);
16878c2ecf20Sopenharmony_ci	memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
16888c2ecf20Sopenharmony_ci	cmd->scsi_done = scsi_mq_done;
16898c2ecf20Sopenharmony_ci
16908c2ecf20Sopenharmony_ci	blk_mq_start_request(req);
16918c2ecf20Sopenharmony_ci	reason = scsi_dispatch_cmd(cmd);
16928c2ecf20Sopenharmony_ci	if (reason) {
16938c2ecf20Sopenharmony_ci		scsi_set_blocked(cmd, reason);
16948c2ecf20Sopenharmony_ci		ret = BLK_STS_RESOURCE;
16958c2ecf20Sopenharmony_ci		goto out_dec_host_busy;
16968c2ecf20Sopenharmony_ci	}
16978c2ecf20Sopenharmony_ci
16988c2ecf20Sopenharmony_ci	return BLK_STS_OK;
16998c2ecf20Sopenharmony_ci
17008c2ecf20Sopenharmony_ciout_dec_host_busy:
17018c2ecf20Sopenharmony_ci	scsi_dec_host_busy(shost, cmd);
17028c2ecf20Sopenharmony_ciout_dec_target_busy:
17038c2ecf20Sopenharmony_ci	if (scsi_target(sdev)->can_queue > 0)
17048c2ecf20Sopenharmony_ci		atomic_dec(&scsi_target(sdev)->target_busy);
17058c2ecf20Sopenharmony_ciout_put_budget:
17068c2ecf20Sopenharmony_ci	scsi_mq_put_budget(q);
17078c2ecf20Sopenharmony_ci	switch (ret) {
17088c2ecf20Sopenharmony_ci	case BLK_STS_OK:
17098c2ecf20Sopenharmony_ci		break;
17108c2ecf20Sopenharmony_ci	case BLK_STS_RESOURCE:
17118c2ecf20Sopenharmony_ci	case BLK_STS_ZONE_RESOURCE:
17128c2ecf20Sopenharmony_ci		if (scsi_device_blocked(sdev))
17138c2ecf20Sopenharmony_ci			ret = BLK_STS_DEV_RESOURCE;
17148c2ecf20Sopenharmony_ci		break;
17158c2ecf20Sopenharmony_ci	default:
17168c2ecf20Sopenharmony_ci		if (unlikely(!scsi_device_online(sdev)))
17178c2ecf20Sopenharmony_ci			scsi_req(req)->result = DID_NO_CONNECT << 16;
17188c2ecf20Sopenharmony_ci		else
17198c2ecf20Sopenharmony_ci			scsi_req(req)->result = DID_ERROR << 16;
17208c2ecf20Sopenharmony_ci		/*
17218c2ecf20Sopenharmony_ci		 * Make sure to release all allocated resources when
17228c2ecf20Sopenharmony_ci		 * we hit an error, as we will never see this command
17238c2ecf20Sopenharmony_ci		 * again.
17248c2ecf20Sopenharmony_ci		 */
17258c2ecf20Sopenharmony_ci		if (req->rq_flags & RQF_DONTPREP)
17268c2ecf20Sopenharmony_ci			scsi_mq_uninit_cmd(cmd);
17278c2ecf20Sopenharmony_ci		scsi_run_queue_async(sdev);
17288c2ecf20Sopenharmony_ci		break;
17298c2ecf20Sopenharmony_ci	}
17308c2ecf20Sopenharmony_ci	return ret;
17318c2ecf20Sopenharmony_ci}
17328c2ecf20Sopenharmony_ci
17338c2ecf20Sopenharmony_cistatic enum blk_eh_timer_return scsi_timeout(struct request *req,
17348c2ecf20Sopenharmony_ci		bool reserved)
17358c2ecf20Sopenharmony_ci{
17368c2ecf20Sopenharmony_ci	if (reserved)
17378c2ecf20Sopenharmony_ci		return BLK_EH_RESET_TIMER;
17388c2ecf20Sopenharmony_ci	return scsi_times_out(req);
17398c2ecf20Sopenharmony_ci}
17408c2ecf20Sopenharmony_ci
17418c2ecf20Sopenharmony_cistatic int scsi_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
17428c2ecf20Sopenharmony_ci				unsigned int hctx_idx, unsigned int numa_node)
17438c2ecf20Sopenharmony_ci{
17448c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = set->driver_data;
17458c2ecf20Sopenharmony_ci	const bool unchecked_isa_dma = shost->unchecked_isa_dma;
17468c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
17478c2ecf20Sopenharmony_ci	struct scatterlist *sg;
17488c2ecf20Sopenharmony_ci	int ret = 0;
17498c2ecf20Sopenharmony_ci
17508c2ecf20Sopenharmony_ci	if (unchecked_isa_dma)
17518c2ecf20Sopenharmony_ci		cmd->flags |= SCMD_UNCHECKED_ISA_DMA;
17528c2ecf20Sopenharmony_ci	cmd->sense_buffer = scsi_alloc_sense_buffer(unchecked_isa_dma,
17538c2ecf20Sopenharmony_ci						    GFP_KERNEL, numa_node);
17548c2ecf20Sopenharmony_ci	if (!cmd->sense_buffer)
17558c2ecf20Sopenharmony_ci		return -ENOMEM;
17568c2ecf20Sopenharmony_ci	cmd->req.sense = cmd->sense_buffer;
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_ci	if (scsi_host_get_prot(shost)) {
17598c2ecf20Sopenharmony_ci		sg = (void *)cmd + sizeof(struct scsi_cmnd) +
17608c2ecf20Sopenharmony_ci			shost->hostt->cmd_size;
17618c2ecf20Sopenharmony_ci		cmd->prot_sdb = (void *)sg + scsi_mq_inline_sgl_size(shost);
17628c2ecf20Sopenharmony_ci	}
17638c2ecf20Sopenharmony_ci
17648c2ecf20Sopenharmony_ci	if (shost->hostt->init_cmd_priv) {
17658c2ecf20Sopenharmony_ci		ret = shost->hostt->init_cmd_priv(shost, cmd);
17668c2ecf20Sopenharmony_ci		if (ret < 0)
17678c2ecf20Sopenharmony_ci			scsi_free_sense_buffer(unchecked_isa_dma,
17688c2ecf20Sopenharmony_ci					       cmd->sense_buffer);
17698c2ecf20Sopenharmony_ci	}
17708c2ecf20Sopenharmony_ci
17718c2ecf20Sopenharmony_ci	return ret;
17728c2ecf20Sopenharmony_ci}
17738c2ecf20Sopenharmony_ci
17748c2ecf20Sopenharmony_cistatic void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq,
17758c2ecf20Sopenharmony_ci				 unsigned int hctx_idx)
17768c2ecf20Sopenharmony_ci{
17778c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = set->driver_data;
17788c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
17798c2ecf20Sopenharmony_ci
17808c2ecf20Sopenharmony_ci	if (shost->hostt->exit_cmd_priv)
17818c2ecf20Sopenharmony_ci		shost->hostt->exit_cmd_priv(shost, cmd);
17828c2ecf20Sopenharmony_ci	scsi_free_sense_buffer(cmd->flags & SCMD_UNCHECKED_ISA_DMA,
17838c2ecf20Sopenharmony_ci			       cmd->sense_buffer);
17848c2ecf20Sopenharmony_ci}
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_cistatic int scsi_map_queues(struct blk_mq_tag_set *set)
17878c2ecf20Sopenharmony_ci{
17888c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set);
17898c2ecf20Sopenharmony_ci
17908c2ecf20Sopenharmony_ci	if (shost->hostt->map_queues)
17918c2ecf20Sopenharmony_ci		return shost->hostt->map_queues(shost);
17928c2ecf20Sopenharmony_ci	return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]);
17938c2ecf20Sopenharmony_ci}
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_civoid __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
17968c2ecf20Sopenharmony_ci{
17978c2ecf20Sopenharmony_ci	struct device *dev = shost->dma_dev;
17988c2ecf20Sopenharmony_ci
17998c2ecf20Sopenharmony_ci	/*
18008c2ecf20Sopenharmony_ci	 * this limit is imposed by hardware restrictions
18018c2ecf20Sopenharmony_ci	 */
18028c2ecf20Sopenharmony_ci	blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize,
18038c2ecf20Sopenharmony_ci					SG_MAX_SEGMENTS));
18048c2ecf20Sopenharmony_ci
18058c2ecf20Sopenharmony_ci	if (scsi_host_prot_dma(shost)) {
18068c2ecf20Sopenharmony_ci		shost->sg_prot_tablesize =
18078c2ecf20Sopenharmony_ci			min_not_zero(shost->sg_prot_tablesize,
18088c2ecf20Sopenharmony_ci				     (unsigned short)SCSI_MAX_PROT_SG_SEGMENTS);
18098c2ecf20Sopenharmony_ci		BUG_ON(shost->sg_prot_tablesize < shost->sg_tablesize);
18108c2ecf20Sopenharmony_ci		blk_queue_max_integrity_segments(q, shost->sg_prot_tablesize);
18118c2ecf20Sopenharmony_ci	}
18128c2ecf20Sopenharmony_ci
18138c2ecf20Sopenharmony_ci	if (dev->dma_mask) {
18148c2ecf20Sopenharmony_ci		shost->max_sectors = min_t(unsigned int, shost->max_sectors,
18158c2ecf20Sopenharmony_ci				dma_max_mapping_size(dev) >> SECTOR_SHIFT);
18168c2ecf20Sopenharmony_ci	}
18178c2ecf20Sopenharmony_ci	blk_queue_max_hw_sectors(q, shost->max_sectors);
18188c2ecf20Sopenharmony_ci	if (shost->unchecked_isa_dma)
18198c2ecf20Sopenharmony_ci		blk_queue_bounce_limit(q, BLK_BOUNCE_ISA);
18208c2ecf20Sopenharmony_ci	blk_queue_segment_boundary(q, shost->dma_boundary);
18218c2ecf20Sopenharmony_ci	dma_set_seg_boundary(dev, shost->dma_boundary);
18228c2ecf20Sopenharmony_ci
18238c2ecf20Sopenharmony_ci	blk_queue_max_segment_size(q, shost->max_segment_size);
18248c2ecf20Sopenharmony_ci	blk_queue_virt_boundary(q, shost->virt_boundary_mask);
18258c2ecf20Sopenharmony_ci	dma_set_max_seg_size(dev, queue_max_segment_size(q));
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_ci	/*
18288c2ecf20Sopenharmony_ci	 * Set a reasonable default alignment:  The larger of 32-byte (dword),
18298c2ecf20Sopenharmony_ci	 * which is a common minimum for HBAs, and the minimum DMA alignment,
18308c2ecf20Sopenharmony_ci	 * which is set by the platform.
18318c2ecf20Sopenharmony_ci	 *
18328c2ecf20Sopenharmony_ci	 * Devices that require a bigger alignment can increase it later.
18338c2ecf20Sopenharmony_ci	 */
18348c2ecf20Sopenharmony_ci	blk_queue_dma_alignment(q, max(4, dma_get_cache_alignment()) - 1);
18358c2ecf20Sopenharmony_ci}
18368c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__scsi_init_queue);
18378c2ecf20Sopenharmony_ci
18388c2ecf20Sopenharmony_cistatic const struct blk_mq_ops scsi_mq_ops_no_commit = {
18398c2ecf20Sopenharmony_ci	.get_budget	= scsi_mq_get_budget,
18408c2ecf20Sopenharmony_ci	.put_budget	= scsi_mq_put_budget,
18418c2ecf20Sopenharmony_ci	.queue_rq	= scsi_queue_rq,
18428c2ecf20Sopenharmony_ci	.complete	= scsi_softirq_done,
18438c2ecf20Sopenharmony_ci	.timeout	= scsi_timeout,
18448c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEBUG_FS
18458c2ecf20Sopenharmony_ci	.show_rq	= scsi_show_rq,
18468c2ecf20Sopenharmony_ci#endif
18478c2ecf20Sopenharmony_ci	.init_request	= scsi_mq_init_request,
18488c2ecf20Sopenharmony_ci	.exit_request	= scsi_mq_exit_request,
18498c2ecf20Sopenharmony_ci	.initialize_rq_fn = scsi_initialize_rq,
18508c2ecf20Sopenharmony_ci	.cleanup_rq	= scsi_cleanup_rq,
18518c2ecf20Sopenharmony_ci	.busy		= scsi_mq_lld_busy,
18528c2ecf20Sopenharmony_ci	.map_queues	= scsi_map_queues,
18538c2ecf20Sopenharmony_ci};
18548c2ecf20Sopenharmony_ci
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_cistatic void scsi_commit_rqs(struct blk_mq_hw_ctx *hctx)
18578c2ecf20Sopenharmony_ci{
18588c2ecf20Sopenharmony_ci	struct request_queue *q = hctx->queue;
18598c2ecf20Sopenharmony_ci	struct scsi_device *sdev = q->queuedata;
18608c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = sdev->host;
18618c2ecf20Sopenharmony_ci
18628c2ecf20Sopenharmony_ci	shost->hostt->commit_rqs(shost, hctx->queue_num);
18638c2ecf20Sopenharmony_ci}
18648c2ecf20Sopenharmony_ci
18658c2ecf20Sopenharmony_cistatic const struct blk_mq_ops scsi_mq_ops = {
18668c2ecf20Sopenharmony_ci	.get_budget	= scsi_mq_get_budget,
18678c2ecf20Sopenharmony_ci	.put_budget	= scsi_mq_put_budget,
18688c2ecf20Sopenharmony_ci	.queue_rq	= scsi_queue_rq,
18698c2ecf20Sopenharmony_ci	.commit_rqs	= scsi_commit_rqs,
18708c2ecf20Sopenharmony_ci	.complete	= scsi_softirq_done,
18718c2ecf20Sopenharmony_ci	.timeout	= scsi_timeout,
18728c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEBUG_FS
18738c2ecf20Sopenharmony_ci	.show_rq	= scsi_show_rq,
18748c2ecf20Sopenharmony_ci#endif
18758c2ecf20Sopenharmony_ci	.init_request	= scsi_mq_init_request,
18768c2ecf20Sopenharmony_ci	.exit_request	= scsi_mq_exit_request,
18778c2ecf20Sopenharmony_ci	.initialize_rq_fn = scsi_initialize_rq,
18788c2ecf20Sopenharmony_ci	.cleanup_rq	= scsi_cleanup_rq,
18798c2ecf20Sopenharmony_ci	.busy		= scsi_mq_lld_busy,
18808c2ecf20Sopenharmony_ci	.map_queues	= scsi_map_queues,
18818c2ecf20Sopenharmony_ci};
18828c2ecf20Sopenharmony_ci
18838c2ecf20Sopenharmony_cistruct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev)
18848c2ecf20Sopenharmony_ci{
18858c2ecf20Sopenharmony_ci	sdev->request_queue = blk_mq_init_queue(&sdev->host->tag_set);
18868c2ecf20Sopenharmony_ci	if (IS_ERR(sdev->request_queue))
18878c2ecf20Sopenharmony_ci		return NULL;
18888c2ecf20Sopenharmony_ci
18898c2ecf20Sopenharmony_ci	sdev->request_queue->queuedata = sdev;
18908c2ecf20Sopenharmony_ci	__scsi_init_queue(sdev->host, sdev->request_queue);
18918c2ecf20Sopenharmony_ci	blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, sdev->request_queue);
18928c2ecf20Sopenharmony_ci	return sdev->request_queue;
18938c2ecf20Sopenharmony_ci}
18948c2ecf20Sopenharmony_ci
18958c2ecf20Sopenharmony_ciint scsi_mq_setup_tags(struct Scsi_Host *shost)
18968c2ecf20Sopenharmony_ci{
18978c2ecf20Sopenharmony_ci	unsigned int cmd_size, sgl_size;
18988c2ecf20Sopenharmony_ci	struct blk_mq_tag_set *tag_set = &shost->tag_set;
18998c2ecf20Sopenharmony_ci
19008c2ecf20Sopenharmony_ci	sgl_size = max_t(unsigned int, sizeof(struct scatterlist),
19018c2ecf20Sopenharmony_ci				scsi_mq_inline_sgl_size(shost));
19028c2ecf20Sopenharmony_ci	cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size + sgl_size;
19038c2ecf20Sopenharmony_ci	if (scsi_host_get_prot(shost))
19048c2ecf20Sopenharmony_ci		cmd_size += sizeof(struct scsi_data_buffer) +
19058c2ecf20Sopenharmony_ci			sizeof(struct scatterlist) * SCSI_INLINE_PROT_SG_CNT;
19068c2ecf20Sopenharmony_ci
19078c2ecf20Sopenharmony_ci	memset(tag_set, 0, sizeof(*tag_set));
19088c2ecf20Sopenharmony_ci	if (shost->hostt->commit_rqs)
19098c2ecf20Sopenharmony_ci		tag_set->ops = &scsi_mq_ops;
19108c2ecf20Sopenharmony_ci	else
19118c2ecf20Sopenharmony_ci		tag_set->ops = &scsi_mq_ops_no_commit;
19128c2ecf20Sopenharmony_ci	tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1;
19138c2ecf20Sopenharmony_ci	tag_set->queue_depth = shost->can_queue;
19148c2ecf20Sopenharmony_ci	tag_set->cmd_size = cmd_size;
19158c2ecf20Sopenharmony_ci	tag_set->numa_node = NUMA_NO_NODE;
19168c2ecf20Sopenharmony_ci	tag_set->flags = BLK_MQ_F_SHOULD_MERGE;
19178c2ecf20Sopenharmony_ci	tag_set->flags |=
19188c2ecf20Sopenharmony_ci		BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy);
19198c2ecf20Sopenharmony_ci	tag_set->driver_data = shost;
19208c2ecf20Sopenharmony_ci	if (shost->host_tagset)
19218c2ecf20Sopenharmony_ci		tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED;
19228c2ecf20Sopenharmony_ci
19238c2ecf20Sopenharmony_ci	return blk_mq_alloc_tag_set(tag_set);
19248c2ecf20Sopenharmony_ci}
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_civoid scsi_mq_destroy_tags(struct Scsi_Host *shost)
19278c2ecf20Sopenharmony_ci{
19288c2ecf20Sopenharmony_ci	blk_mq_free_tag_set(&shost->tag_set);
19298c2ecf20Sopenharmony_ci}
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci/**
19328c2ecf20Sopenharmony_ci * scsi_device_from_queue - return sdev associated with a request_queue
19338c2ecf20Sopenharmony_ci * @q: The request queue to return the sdev from
19348c2ecf20Sopenharmony_ci *
19358c2ecf20Sopenharmony_ci * Return the sdev associated with a request queue or NULL if the
19368c2ecf20Sopenharmony_ci * request_queue does not reference a SCSI device.
19378c2ecf20Sopenharmony_ci */
19388c2ecf20Sopenharmony_cistruct scsi_device *scsi_device_from_queue(struct request_queue *q)
19398c2ecf20Sopenharmony_ci{
19408c2ecf20Sopenharmony_ci	struct scsi_device *sdev = NULL;
19418c2ecf20Sopenharmony_ci
19428c2ecf20Sopenharmony_ci	if (q->mq_ops == &scsi_mq_ops_no_commit ||
19438c2ecf20Sopenharmony_ci	    q->mq_ops == &scsi_mq_ops)
19448c2ecf20Sopenharmony_ci		sdev = q->queuedata;
19458c2ecf20Sopenharmony_ci	if (!sdev || !get_device(&sdev->sdev_gendev))
19468c2ecf20Sopenharmony_ci		sdev = NULL;
19478c2ecf20Sopenharmony_ci
19488c2ecf20Sopenharmony_ci	return sdev;
19498c2ecf20Sopenharmony_ci}
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ci/**
19528c2ecf20Sopenharmony_ci * scsi_block_requests - Utility function used by low-level drivers to prevent
19538c2ecf20Sopenharmony_ci * further commands from being queued to the device.
19548c2ecf20Sopenharmony_ci * @shost:  host in question
19558c2ecf20Sopenharmony_ci *
19568c2ecf20Sopenharmony_ci * There is no timer nor any other means by which the requests get unblocked
19578c2ecf20Sopenharmony_ci * other than the low-level driver calling scsi_unblock_requests().
19588c2ecf20Sopenharmony_ci */
19598c2ecf20Sopenharmony_civoid scsi_block_requests(struct Scsi_Host *shost)
19608c2ecf20Sopenharmony_ci{
19618c2ecf20Sopenharmony_ci	shost->host_self_blocked = 1;
19628c2ecf20Sopenharmony_ci}
19638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_block_requests);
19648c2ecf20Sopenharmony_ci
19658c2ecf20Sopenharmony_ci/**
19668c2ecf20Sopenharmony_ci * scsi_unblock_requests - Utility function used by low-level drivers to allow
19678c2ecf20Sopenharmony_ci * further commands to be queued to the device.
19688c2ecf20Sopenharmony_ci * @shost:  host in question
19698c2ecf20Sopenharmony_ci *
19708c2ecf20Sopenharmony_ci * There is no timer nor any other means by which the requests get unblocked
19718c2ecf20Sopenharmony_ci * other than the low-level driver calling scsi_unblock_requests(). This is done
19728c2ecf20Sopenharmony_ci * as an API function so that changes to the internals of the scsi mid-layer
19738c2ecf20Sopenharmony_ci * won't require wholesale changes to drivers that use this feature.
19748c2ecf20Sopenharmony_ci */
19758c2ecf20Sopenharmony_civoid scsi_unblock_requests(struct Scsi_Host *shost)
19768c2ecf20Sopenharmony_ci{
19778c2ecf20Sopenharmony_ci	shost->host_self_blocked = 0;
19788c2ecf20Sopenharmony_ci	scsi_run_host_queues(shost);
19798c2ecf20Sopenharmony_ci}
19808c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_unblock_requests);
19818c2ecf20Sopenharmony_ci
19828c2ecf20Sopenharmony_civoid scsi_exit_queue(void)
19838c2ecf20Sopenharmony_ci{
19848c2ecf20Sopenharmony_ci	kmem_cache_destroy(scsi_sense_cache);
19858c2ecf20Sopenharmony_ci	kmem_cache_destroy(scsi_sense_isadma_cache);
19868c2ecf20Sopenharmony_ci}
19878c2ecf20Sopenharmony_ci
19888c2ecf20Sopenharmony_ci/**
19898c2ecf20Sopenharmony_ci *	scsi_mode_select - issue a mode select
19908c2ecf20Sopenharmony_ci *	@sdev:	SCSI device to be queried
19918c2ecf20Sopenharmony_ci *	@pf:	Page format bit (1 == standard, 0 == vendor specific)
19928c2ecf20Sopenharmony_ci *	@sp:	Save page bit (0 == don't save, 1 == save)
19938c2ecf20Sopenharmony_ci *	@modepage: mode page being requested
19948c2ecf20Sopenharmony_ci *	@buffer: request buffer (may not be smaller than eight bytes)
19958c2ecf20Sopenharmony_ci *	@len:	length of request buffer.
19968c2ecf20Sopenharmony_ci *	@timeout: command timeout
19978c2ecf20Sopenharmony_ci *	@retries: number of retries before failing
19988c2ecf20Sopenharmony_ci *	@data: returns a structure abstracting the mode header data
19998c2ecf20Sopenharmony_ci *	@sshdr: place to put sense data (or NULL if no sense to be collected).
20008c2ecf20Sopenharmony_ci *		must be SCSI_SENSE_BUFFERSIZE big.
20018c2ecf20Sopenharmony_ci *
20028c2ecf20Sopenharmony_ci *	Returns zero if successful; negative error number or scsi
20038c2ecf20Sopenharmony_ci *	status on error
20048c2ecf20Sopenharmony_ci *
20058c2ecf20Sopenharmony_ci */
20068c2ecf20Sopenharmony_ciint
20078c2ecf20Sopenharmony_ciscsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage,
20088c2ecf20Sopenharmony_ci		 unsigned char *buffer, int len, int timeout, int retries,
20098c2ecf20Sopenharmony_ci		 struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr)
20108c2ecf20Sopenharmony_ci{
20118c2ecf20Sopenharmony_ci	unsigned char cmd[10];
20128c2ecf20Sopenharmony_ci	unsigned char *real_buffer;
20138c2ecf20Sopenharmony_ci	int ret;
20148c2ecf20Sopenharmony_ci
20158c2ecf20Sopenharmony_ci	memset(cmd, 0, sizeof(cmd));
20168c2ecf20Sopenharmony_ci	cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0);
20178c2ecf20Sopenharmony_ci
20188c2ecf20Sopenharmony_ci	if (sdev->use_10_for_ms) {
20198c2ecf20Sopenharmony_ci		if (len > 65535)
20208c2ecf20Sopenharmony_ci			return -EINVAL;
20218c2ecf20Sopenharmony_ci		real_buffer = kmalloc(8 + len, GFP_KERNEL);
20228c2ecf20Sopenharmony_ci		if (!real_buffer)
20238c2ecf20Sopenharmony_ci			return -ENOMEM;
20248c2ecf20Sopenharmony_ci		memcpy(real_buffer + 8, buffer, len);
20258c2ecf20Sopenharmony_ci		len += 8;
20268c2ecf20Sopenharmony_ci		real_buffer[0] = 0;
20278c2ecf20Sopenharmony_ci		real_buffer[1] = 0;
20288c2ecf20Sopenharmony_ci		real_buffer[2] = data->medium_type;
20298c2ecf20Sopenharmony_ci		real_buffer[3] = data->device_specific;
20308c2ecf20Sopenharmony_ci		real_buffer[4] = data->longlba ? 0x01 : 0;
20318c2ecf20Sopenharmony_ci		real_buffer[5] = 0;
20328c2ecf20Sopenharmony_ci		real_buffer[6] = data->block_descriptor_length >> 8;
20338c2ecf20Sopenharmony_ci		real_buffer[7] = data->block_descriptor_length;
20348c2ecf20Sopenharmony_ci
20358c2ecf20Sopenharmony_ci		cmd[0] = MODE_SELECT_10;
20368c2ecf20Sopenharmony_ci		cmd[7] = len >> 8;
20378c2ecf20Sopenharmony_ci		cmd[8] = len;
20388c2ecf20Sopenharmony_ci	} else {
20398c2ecf20Sopenharmony_ci		if (len > 255 || data->block_descriptor_length > 255 ||
20408c2ecf20Sopenharmony_ci		    data->longlba)
20418c2ecf20Sopenharmony_ci			return -EINVAL;
20428c2ecf20Sopenharmony_ci
20438c2ecf20Sopenharmony_ci		real_buffer = kmalloc(4 + len, GFP_KERNEL);
20448c2ecf20Sopenharmony_ci		if (!real_buffer)
20458c2ecf20Sopenharmony_ci			return -ENOMEM;
20468c2ecf20Sopenharmony_ci		memcpy(real_buffer + 4, buffer, len);
20478c2ecf20Sopenharmony_ci		len += 4;
20488c2ecf20Sopenharmony_ci		real_buffer[0] = 0;
20498c2ecf20Sopenharmony_ci		real_buffer[1] = data->medium_type;
20508c2ecf20Sopenharmony_ci		real_buffer[2] = data->device_specific;
20518c2ecf20Sopenharmony_ci		real_buffer[3] = data->block_descriptor_length;
20528c2ecf20Sopenharmony_ci
20538c2ecf20Sopenharmony_ci		cmd[0] = MODE_SELECT;
20548c2ecf20Sopenharmony_ci		cmd[4] = len;
20558c2ecf20Sopenharmony_ci	}
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci	ret = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, real_buffer, len,
20588c2ecf20Sopenharmony_ci			       sshdr, timeout, retries, NULL);
20598c2ecf20Sopenharmony_ci	kfree(real_buffer);
20608c2ecf20Sopenharmony_ci	return ret;
20618c2ecf20Sopenharmony_ci}
20628c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_mode_select);
20638c2ecf20Sopenharmony_ci
20648c2ecf20Sopenharmony_ci/**
20658c2ecf20Sopenharmony_ci *	scsi_mode_sense - issue a mode sense, falling back from 10 to six bytes if necessary.
20668c2ecf20Sopenharmony_ci *	@sdev:	SCSI device to be queried
20678c2ecf20Sopenharmony_ci *	@dbd:	set to prevent mode sense from returning block descriptors
20688c2ecf20Sopenharmony_ci *	@modepage: mode page being requested
20698c2ecf20Sopenharmony_ci *	@buffer: request buffer (may not be smaller than eight bytes)
20708c2ecf20Sopenharmony_ci *	@len:	length of request buffer.
20718c2ecf20Sopenharmony_ci *	@timeout: command timeout
20728c2ecf20Sopenharmony_ci *	@retries: number of retries before failing
20738c2ecf20Sopenharmony_ci *	@data: returns a structure abstracting the mode header data
20748c2ecf20Sopenharmony_ci *	@sshdr: place to put sense data (or NULL if no sense to be collected).
20758c2ecf20Sopenharmony_ci *		must be SCSI_SENSE_BUFFERSIZE big.
20768c2ecf20Sopenharmony_ci *
20778c2ecf20Sopenharmony_ci *	Returns zero if successful, or a negative error number on failure
20788c2ecf20Sopenharmony_ci */
20798c2ecf20Sopenharmony_ciint
20808c2ecf20Sopenharmony_ciscsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
20818c2ecf20Sopenharmony_ci		  unsigned char *buffer, int len, int timeout, int retries,
20828c2ecf20Sopenharmony_ci		  struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr)
20838c2ecf20Sopenharmony_ci{
20848c2ecf20Sopenharmony_ci	unsigned char cmd[12];
20858c2ecf20Sopenharmony_ci	int use_10_for_ms;
20868c2ecf20Sopenharmony_ci	int header_length;
20878c2ecf20Sopenharmony_ci	int result, retry_count = retries;
20888c2ecf20Sopenharmony_ci	struct scsi_sense_hdr my_sshdr;
20898c2ecf20Sopenharmony_ci
20908c2ecf20Sopenharmony_ci	memset(data, 0, sizeof(*data));
20918c2ecf20Sopenharmony_ci	memset(&cmd[0], 0, 12);
20928c2ecf20Sopenharmony_ci
20938c2ecf20Sopenharmony_ci	dbd = sdev->set_dbd_for_ms ? 8 : dbd;
20948c2ecf20Sopenharmony_ci	cmd[1] = dbd & 0x18;	/* allows DBD and LLBA bits */
20958c2ecf20Sopenharmony_ci	cmd[2] = modepage;
20968c2ecf20Sopenharmony_ci
20978c2ecf20Sopenharmony_ci	/* caller might not be interested in sense, but we need it */
20988c2ecf20Sopenharmony_ci	if (!sshdr)
20998c2ecf20Sopenharmony_ci		sshdr = &my_sshdr;
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_ci retry:
21028c2ecf20Sopenharmony_ci	use_10_for_ms = sdev->use_10_for_ms || len > 255;
21038c2ecf20Sopenharmony_ci
21048c2ecf20Sopenharmony_ci	if (use_10_for_ms) {
21058c2ecf20Sopenharmony_ci		if (len < 8 || len > 65535)
21068c2ecf20Sopenharmony_ci			return -EINVAL;
21078c2ecf20Sopenharmony_ci
21088c2ecf20Sopenharmony_ci		cmd[0] = MODE_SENSE_10;
21098c2ecf20Sopenharmony_ci		put_unaligned_be16(len, &cmd[7]);
21108c2ecf20Sopenharmony_ci		header_length = 8;
21118c2ecf20Sopenharmony_ci	} else {
21128c2ecf20Sopenharmony_ci		if (len < 4)
21138c2ecf20Sopenharmony_ci			return -EINVAL;
21148c2ecf20Sopenharmony_ci
21158c2ecf20Sopenharmony_ci		cmd[0] = MODE_SENSE;
21168c2ecf20Sopenharmony_ci		cmd[4] = len;
21178c2ecf20Sopenharmony_ci		header_length = 4;
21188c2ecf20Sopenharmony_ci	}
21198c2ecf20Sopenharmony_ci
21208c2ecf20Sopenharmony_ci	memset(buffer, 0, len);
21218c2ecf20Sopenharmony_ci
21228c2ecf20Sopenharmony_ci	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
21238c2ecf20Sopenharmony_ci				  sshdr, timeout, retries, NULL);
21248c2ecf20Sopenharmony_ci	if (result < 0)
21258c2ecf20Sopenharmony_ci		return result;
21268c2ecf20Sopenharmony_ci
21278c2ecf20Sopenharmony_ci	/* This code looks awful: what it's doing is making sure an
21288c2ecf20Sopenharmony_ci	 * ILLEGAL REQUEST sense return identifies the actual command
21298c2ecf20Sopenharmony_ci	 * byte as the problem.  MODE_SENSE commands can return
21308c2ecf20Sopenharmony_ci	 * ILLEGAL REQUEST if the code page isn't supported */
21318c2ecf20Sopenharmony_ci
21328c2ecf20Sopenharmony_ci	if (use_10_for_ms && !scsi_status_is_good(result) &&
21338c2ecf20Sopenharmony_ci	    driver_byte(result) == DRIVER_SENSE) {
21348c2ecf20Sopenharmony_ci		if (scsi_sense_valid(sshdr)) {
21358c2ecf20Sopenharmony_ci			if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
21368c2ecf20Sopenharmony_ci			    (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
21378c2ecf20Sopenharmony_ci				/*
21388c2ecf20Sopenharmony_ci				 * Invalid command operation code: retry using
21398c2ecf20Sopenharmony_ci				 * MODE SENSE(6) if this was a MODE SENSE(10)
21408c2ecf20Sopenharmony_ci				 * request, except if the request mode page is
21418c2ecf20Sopenharmony_ci				 * too large for MODE SENSE single byte
21428c2ecf20Sopenharmony_ci				 * allocation length field.
21438c2ecf20Sopenharmony_ci				 */
21448c2ecf20Sopenharmony_ci				sdev->use_10_for_ms = 0;
21458c2ecf20Sopenharmony_ci				goto retry;
21468c2ecf20Sopenharmony_ci			}
21478c2ecf20Sopenharmony_ci		}
21488c2ecf20Sopenharmony_ci	}
21498c2ecf20Sopenharmony_ci
21508c2ecf20Sopenharmony_ci	if (scsi_status_is_good(result)) {
21518c2ecf20Sopenharmony_ci		if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b &&
21528c2ecf20Sopenharmony_ci			     (modepage == 6 || modepage == 8))) {
21538c2ecf20Sopenharmony_ci			/* Initio breakage? */
21548c2ecf20Sopenharmony_ci			header_length = 0;
21558c2ecf20Sopenharmony_ci			data->length = 13;
21568c2ecf20Sopenharmony_ci			data->medium_type = 0;
21578c2ecf20Sopenharmony_ci			data->device_specific = 0;
21588c2ecf20Sopenharmony_ci			data->longlba = 0;
21598c2ecf20Sopenharmony_ci			data->block_descriptor_length = 0;
21608c2ecf20Sopenharmony_ci		} else if (use_10_for_ms) {
21618c2ecf20Sopenharmony_ci			data->length = get_unaligned_be16(&buffer[0]) + 2;
21628c2ecf20Sopenharmony_ci			data->medium_type = buffer[2];
21638c2ecf20Sopenharmony_ci			data->device_specific = buffer[3];
21648c2ecf20Sopenharmony_ci			data->longlba = buffer[4] & 0x01;
21658c2ecf20Sopenharmony_ci			data->block_descriptor_length = get_unaligned_be16(&buffer[6]);
21668c2ecf20Sopenharmony_ci		} else {
21678c2ecf20Sopenharmony_ci			data->length = buffer[0] + 1;
21688c2ecf20Sopenharmony_ci			data->medium_type = buffer[1];
21698c2ecf20Sopenharmony_ci			data->device_specific = buffer[2];
21708c2ecf20Sopenharmony_ci			data->block_descriptor_length = buffer[3];
21718c2ecf20Sopenharmony_ci		}
21728c2ecf20Sopenharmony_ci		data->header_length = header_length;
21738c2ecf20Sopenharmony_ci		result = 0;
21748c2ecf20Sopenharmony_ci	} else if ((status_byte(result) == CHECK_CONDITION) &&
21758c2ecf20Sopenharmony_ci		   scsi_sense_valid(sshdr) &&
21768c2ecf20Sopenharmony_ci		   sshdr->sense_key == UNIT_ATTENTION && retry_count) {
21778c2ecf20Sopenharmony_ci		retry_count--;
21788c2ecf20Sopenharmony_ci		goto retry;
21798c2ecf20Sopenharmony_ci	}
21808c2ecf20Sopenharmony_ci	if (result > 0)
21818c2ecf20Sopenharmony_ci		result = -EIO;
21828c2ecf20Sopenharmony_ci	return result;
21838c2ecf20Sopenharmony_ci}
21848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_mode_sense);
21858c2ecf20Sopenharmony_ci
21868c2ecf20Sopenharmony_ci/**
21878c2ecf20Sopenharmony_ci *	scsi_test_unit_ready - test if unit is ready
21888c2ecf20Sopenharmony_ci *	@sdev:	scsi device to change the state of.
21898c2ecf20Sopenharmony_ci *	@timeout: command timeout
21908c2ecf20Sopenharmony_ci *	@retries: number of retries before failing
21918c2ecf20Sopenharmony_ci *	@sshdr: outpout pointer for decoded sense information.
21928c2ecf20Sopenharmony_ci *
21938c2ecf20Sopenharmony_ci *	Returns zero if unsuccessful or an error if TUR failed.  For
21948c2ecf20Sopenharmony_ci *	removable media, UNIT_ATTENTION sets ->changed flag.
21958c2ecf20Sopenharmony_ci **/
21968c2ecf20Sopenharmony_ciint
21978c2ecf20Sopenharmony_ciscsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
21988c2ecf20Sopenharmony_ci		     struct scsi_sense_hdr *sshdr)
21998c2ecf20Sopenharmony_ci{
22008c2ecf20Sopenharmony_ci	char cmd[] = {
22018c2ecf20Sopenharmony_ci		TEST_UNIT_READY, 0, 0, 0, 0, 0,
22028c2ecf20Sopenharmony_ci	};
22038c2ecf20Sopenharmony_ci	int result;
22048c2ecf20Sopenharmony_ci
22058c2ecf20Sopenharmony_ci	/* try to eat the UNIT_ATTENTION if there are enough retries */
22068c2ecf20Sopenharmony_ci	do {
22078c2ecf20Sopenharmony_ci		result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr,
22088c2ecf20Sopenharmony_ci					  timeout, 1, NULL);
22098c2ecf20Sopenharmony_ci		if (sdev->removable && scsi_sense_valid(sshdr) &&
22108c2ecf20Sopenharmony_ci		    sshdr->sense_key == UNIT_ATTENTION)
22118c2ecf20Sopenharmony_ci			sdev->changed = 1;
22128c2ecf20Sopenharmony_ci	} while (scsi_sense_valid(sshdr) &&
22138c2ecf20Sopenharmony_ci		 sshdr->sense_key == UNIT_ATTENTION && --retries);
22148c2ecf20Sopenharmony_ci
22158c2ecf20Sopenharmony_ci	return result;
22168c2ecf20Sopenharmony_ci}
22178c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_test_unit_ready);
22188c2ecf20Sopenharmony_ci
22198c2ecf20Sopenharmony_ci/**
22208c2ecf20Sopenharmony_ci *	scsi_device_set_state - Take the given device through the device state model.
22218c2ecf20Sopenharmony_ci *	@sdev:	scsi device to change the state of.
22228c2ecf20Sopenharmony_ci *	@state:	state to change to.
22238c2ecf20Sopenharmony_ci *
22248c2ecf20Sopenharmony_ci *	Returns zero if successful or an error if the requested
22258c2ecf20Sopenharmony_ci *	transition is illegal.
22268c2ecf20Sopenharmony_ci */
22278c2ecf20Sopenharmony_ciint
22288c2ecf20Sopenharmony_ciscsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
22298c2ecf20Sopenharmony_ci{
22308c2ecf20Sopenharmony_ci	enum scsi_device_state oldstate = sdev->sdev_state;
22318c2ecf20Sopenharmony_ci
22328c2ecf20Sopenharmony_ci	if (state == oldstate)
22338c2ecf20Sopenharmony_ci		return 0;
22348c2ecf20Sopenharmony_ci
22358c2ecf20Sopenharmony_ci	switch (state) {
22368c2ecf20Sopenharmony_ci	case SDEV_CREATED:
22378c2ecf20Sopenharmony_ci		switch (oldstate) {
22388c2ecf20Sopenharmony_ci		case SDEV_CREATED_BLOCK:
22398c2ecf20Sopenharmony_ci			break;
22408c2ecf20Sopenharmony_ci		default:
22418c2ecf20Sopenharmony_ci			goto illegal;
22428c2ecf20Sopenharmony_ci		}
22438c2ecf20Sopenharmony_ci		break;
22448c2ecf20Sopenharmony_ci
22458c2ecf20Sopenharmony_ci	case SDEV_RUNNING:
22468c2ecf20Sopenharmony_ci		switch (oldstate) {
22478c2ecf20Sopenharmony_ci		case SDEV_CREATED:
22488c2ecf20Sopenharmony_ci		case SDEV_OFFLINE:
22498c2ecf20Sopenharmony_ci		case SDEV_TRANSPORT_OFFLINE:
22508c2ecf20Sopenharmony_ci		case SDEV_QUIESCE:
22518c2ecf20Sopenharmony_ci		case SDEV_BLOCK:
22528c2ecf20Sopenharmony_ci			break;
22538c2ecf20Sopenharmony_ci		default:
22548c2ecf20Sopenharmony_ci			goto illegal;
22558c2ecf20Sopenharmony_ci		}
22568c2ecf20Sopenharmony_ci		break;
22578c2ecf20Sopenharmony_ci
22588c2ecf20Sopenharmony_ci	case SDEV_QUIESCE:
22598c2ecf20Sopenharmony_ci		switch (oldstate) {
22608c2ecf20Sopenharmony_ci		case SDEV_RUNNING:
22618c2ecf20Sopenharmony_ci		case SDEV_OFFLINE:
22628c2ecf20Sopenharmony_ci		case SDEV_TRANSPORT_OFFLINE:
22638c2ecf20Sopenharmony_ci			break;
22648c2ecf20Sopenharmony_ci		default:
22658c2ecf20Sopenharmony_ci			goto illegal;
22668c2ecf20Sopenharmony_ci		}
22678c2ecf20Sopenharmony_ci		break;
22688c2ecf20Sopenharmony_ci
22698c2ecf20Sopenharmony_ci	case SDEV_OFFLINE:
22708c2ecf20Sopenharmony_ci	case SDEV_TRANSPORT_OFFLINE:
22718c2ecf20Sopenharmony_ci		switch (oldstate) {
22728c2ecf20Sopenharmony_ci		case SDEV_CREATED:
22738c2ecf20Sopenharmony_ci		case SDEV_RUNNING:
22748c2ecf20Sopenharmony_ci		case SDEV_QUIESCE:
22758c2ecf20Sopenharmony_ci		case SDEV_BLOCK:
22768c2ecf20Sopenharmony_ci			break;
22778c2ecf20Sopenharmony_ci		default:
22788c2ecf20Sopenharmony_ci			goto illegal;
22798c2ecf20Sopenharmony_ci		}
22808c2ecf20Sopenharmony_ci		break;
22818c2ecf20Sopenharmony_ci
22828c2ecf20Sopenharmony_ci	case SDEV_BLOCK:
22838c2ecf20Sopenharmony_ci		switch (oldstate) {
22848c2ecf20Sopenharmony_ci		case SDEV_RUNNING:
22858c2ecf20Sopenharmony_ci		case SDEV_CREATED_BLOCK:
22868c2ecf20Sopenharmony_ci		case SDEV_QUIESCE:
22878c2ecf20Sopenharmony_ci		case SDEV_OFFLINE:
22888c2ecf20Sopenharmony_ci			break;
22898c2ecf20Sopenharmony_ci		default:
22908c2ecf20Sopenharmony_ci			goto illegal;
22918c2ecf20Sopenharmony_ci		}
22928c2ecf20Sopenharmony_ci		break;
22938c2ecf20Sopenharmony_ci
22948c2ecf20Sopenharmony_ci	case SDEV_CREATED_BLOCK:
22958c2ecf20Sopenharmony_ci		switch (oldstate) {
22968c2ecf20Sopenharmony_ci		case SDEV_CREATED:
22978c2ecf20Sopenharmony_ci			break;
22988c2ecf20Sopenharmony_ci		default:
22998c2ecf20Sopenharmony_ci			goto illegal;
23008c2ecf20Sopenharmony_ci		}
23018c2ecf20Sopenharmony_ci		break;
23028c2ecf20Sopenharmony_ci
23038c2ecf20Sopenharmony_ci	case SDEV_CANCEL:
23048c2ecf20Sopenharmony_ci		switch (oldstate) {
23058c2ecf20Sopenharmony_ci		case SDEV_CREATED:
23068c2ecf20Sopenharmony_ci		case SDEV_RUNNING:
23078c2ecf20Sopenharmony_ci		case SDEV_QUIESCE:
23088c2ecf20Sopenharmony_ci		case SDEV_OFFLINE:
23098c2ecf20Sopenharmony_ci		case SDEV_TRANSPORT_OFFLINE:
23108c2ecf20Sopenharmony_ci			break;
23118c2ecf20Sopenharmony_ci		default:
23128c2ecf20Sopenharmony_ci			goto illegal;
23138c2ecf20Sopenharmony_ci		}
23148c2ecf20Sopenharmony_ci		break;
23158c2ecf20Sopenharmony_ci
23168c2ecf20Sopenharmony_ci	case SDEV_DEL:
23178c2ecf20Sopenharmony_ci		switch (oldstate) {
23188c2ecf20Sopenharmony_ci		case SDEV_CREATED:
23198c2ecf20Sopenharmony_ci		case SDEV_RUNNING:
23208c2ecf20Sopenharmony_ci		case SDEV_OFFLINE:
23218c2ecf20Sopenharmony_ci		case SDEV_TRANSPORT_OFFLINE:
23228c2ecf20Sopenharmony_ci		case SDEV_CANCEL:
23238c2ecf20Sopenharmony_ci		case SDEV_BLOCK:
23248c2ecf20Sopenharmony_ci		case SDEV_CREATED_BLOCK:
23258c2ecf20Sopenharmony_ci			break;
23268c2ecf20Sopenharmony_ci		default:
23278c2ecf20Sopenharmony_ci			goto illegal;
23288c2ecf20Sopenharmony_ci		}
23298c2ecf20Sopenharmony_ci		break;
23308c2ecf20Sopenharmony_ci
23318c2ecf20Sopenharmony_ci	}
23328c2ecf20Sopenharmony_ci	sdev->offline_already = false;
23338c2ecf20Sopenharmony_ci	sdev->sdev_state = state;
23348c2ecf20Sopenharmony_ci	return 0;
23358c2ecf20Sopenharmony_ci
23368c2ecf20Sopenharmony_ci illegal:
23378c2ecf20Sopenharmony_ci	SCSI_LOG_ERROR_RECOVERY(1,
23388c2ecf20Sopenharmony_ci				sdev_printk(KERN_ERR, sdev,
23398c2ecf20Sopenharmony_ci					    "Illegal state transition %s->%s",
23408c2ecf20Sopenharmony_ci					    scsi_device_state_name(oldstate),
23418c2ecf20Sopenharmony_ci					    scsi_device_state_name(state))
23428c2ecf20Sopenharmony_ci				);
23438c2ecf20Sopenharmony_ci	return -EINVAL;
23448c2ecf20Sopenharmony_ci}
23458c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_device_set_state);
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci/**
23488c2ecf20Sopenharmony_ci * 	sdev_evt_emit - emit a single SCSI device uevent
23498c2ecf20Sopenharmony_ci *	@sdev: associated SCSI device
23508c2ecf20Sopenharmony_ci *	@evt: event to emit
23518c2ecf20Sopenharmony_ci *
23528c2ecf20Sopenharmony_ci *	Send a single uevent (scsi_event) to the associated scsi_device.
23538c2ecf20Sopenharmony_ci */
23548c2ecf20Sopenharmony_cistatic void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt)
23558c2ecf20Sopenharmony_ci{
23568c2ecf20Sopenharmony_ci	int idx = 0;
23578c2ecf20Sopenharmony_ci	char *envp[3];
23588c2ecf20Sopenharmony_ci
23598c2ecf20Sopenharmony_ci	switch (evt->evt_type) {
23608c2ecf20Sopenharmony_ci	case SDEV_EVT_MEDIA_CHANGE:
23618c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_MEDIA_CHANGE=1";
23628c2ecf20Sopenharmony_ci		break;
23638c2ecf20Sopenharmony_ci	case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
23648c2ecf20Sopenharmony_ci		scsi_rescan_device(&sdev->sdev_gendev);
23658c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED";
23668c2ecf20Sopenharmony_ci		break;
23678c2ecf20Sopenharmony_ci	case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
23688c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=CAPACITY_DATA_HAS_CHANGED";
23698c2ecf20Sopenharmony_ci		break;
23708c2ecf20Sopenharmony_ci	case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
23718c2ecf20Sopenharmony_ci	       envp[idx++] = "SDEV_UA=THIN_PROVISIONING_SOFT_THRESHOLD_REACHED";
23728c2ecf20Sopenharmony_ci		break;
23738c2ecf20Sopenharmony_ci	case SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED:
23748c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=MODE_PARAMETERS_CHANGED";
23758c2ecf20Sopenharmony_ci		break;
23768c2ecf20Sopenharmony_ci	case SDEV_EVT_LUN_CHANGE_REPORTED:
23778c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=REPORTED_LUNS_DATA_HAS_CHANGED";
23788c2ecf20Sopenharmony_ci		break;
23798c2ecf20Sopenharmony_ci	case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
23808c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=ASYMMETRIC_ACCESS_STATE_CHANGED";
23818c2ecf20Sopenharmony_ci		break;
23828c2ecf20Sopenharmony_ci	case SDEV_EVT_POWER_ON_RESET_OCCURRED:
23838c2ecf20Sopenharmony_ci		envp[idx++] = "SDEV_UA=POWER_ON_RESET_OCCURRED";
23848c2ecf20Sopenharmony_ci		break;
23858c2ecf20Sopenharmony_ci	default:
23868c2ecf20Sopenharmony_ci		/* do nothing */
23878c2ecf20Sopenharmony_ci		break;
23888c2ecf20Sopenharmony_ci	}
23898c2ecf20Sopenharmony_ci
23908c2ecf20Sopenharmony_ci	envp[idx++] = NULL;
23918c2ecf20Sopenharmony_ci
23928c2ecf20Sopenharmony_ci	kobject_uevent_env(&sdev->sdev_gendev.kobj, KOBJ_CHANGE, envp);
23938c2ecf20Sopenharmony_ci}
23948c2ecf20Sopenharmony_ci
23958c2ecf20Sopenharmony_ci/**
23968c2ecf20Sopenharmony_ci * 	sdev_evt_thread - send a uevent for each scsi event
23978c2ecf20Sopenharmony_ci *	@work: work struct for scsi_device
23988c2ecf20Sopenharmony_ci *
23998c2ecf20Sopenharmony_ci *	Dispatch queued events to their associated scsi_device kobjects
24008c2ecf20Sopenharmony_ci *	as uevents.
24018c2ecf20Sopenharmony_ci */
24028c2ecf20Sopenharmony_civoid scsi_evt_thread(struct work_struct *work)
24038c2ecf20Sopenharmony_ci{
24048c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
24058c2ecf20Sopenharmony_ci	enum scsi_device_event evt_type;
24068c2ecf20Sopenharmony_ci	LIST_HEAD(event_list);
24078c2ecf20Sopenharmony_ci
24088c2ecf20Sopenharmony_ci	sdev = container_of(work, struct scsi_device, event_work);
24098c2ecf20Sopenharmony_ci
24108c2ecf20Sopenharmony_ci	for (evt_type = SDEV_EVT_FIRST; evt_type <= SDEV_EVT_LAST; evt_type++)
24118c2ecf20Sopenharmony_ci		if (test_and_clear_bit(evt_type, sdev->pending_events))
24128c2ecf20Sopenharmony_ci			sdev_evt_send_simple(sdev, evt_type, GFP_KERNEL);
24138c2ecf20Sopenharmony_ci
24148c2ecf20Sopenharmony_ci	while (1) {
24158c2ecf20Sopenharmony_ci		struct scsi_event *evt;
24168c2ecf20Sopenharmony_ci		struct list_head *this, *tmp;
24178c2ecf20Sopenharmony_ci		unsigned long flags;
24188c2ecf20Sopenharmony_ci
24198c2ecf20Sopenharmony_ci		spin_lock_irqsave(&sdev->list_lock, flags);
24208c2ecf20Sopenharmony_ci		list_splice_init(&sdev->event_list, &event_list);
24218c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&sdev->list_lock, flags);
24228c2ecf20Sopenharmony_ci
24238c2ecf20Sopenharmony_ci		if (list_empty(&event_list))
24248c2ecf20Sopenharmony_ci			break;
24258c2ecf20Sopenharmony_ci
24268c2ecf20Sopenharmony_ci		list_for_each_safe(this, tmp, &event_list) {
24278c2ecf20Sopenharmony_ci			evt = list_entry(this, struct scsi_event, node);
24288c2ecf20Sopenharmony_ci			list_del(&evt->node);
24298c2ecf20Sopenharmony_ci			scsi_evt_emit(sdev, evt);
24308c2ecf20Sopenharmony_ci			kfree(evt);
24318c2ecf20Sopenharmony_ci		}
24328c2ecf20Sopenharmony_ci	}
24338c2ecf20Sopenharmony_ci}
24348c2ecf20Sopenharmony_ci
24358c2ecf20Sopenharmony_ci/**
24368c2ecf20Sopenharmony_ci * 	sdev_evt_send - send asserted event to uevent thread
24378c2ecf20Sopenharmony_ci *	@sdev: scsi_device event occurred on
24388c2ecf20Sopenharmony_ci *	@evt: event to send
24398c2ecf20Sopenharmony_ci *
24408c2ecf20Sopenharmony_ci *	Assert scsi device event asynchronously.
24418c2ecf20Sopenharmony_ci */
24428c2ecf20Sopenharmony_civoid sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt)
24438c2ecf20Sopenharmony_ci{
24448c2ecf20Sopenharmony_ci	unsigned long flags;
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci#if 0
24478c2ecf20Sopenharmony_ci	/* FIXME: currently this check eliminates all media change events
24488c2ecf20Sopenharmony_ci	 * for polled devices.  Need to update to discriminate between AN
24498c2ecf20Sopenharmony_ci	 * and polled events */
24508c2ecf20Sopenharmony_ci	if (!test_bit(evt->evt_type, sdev->supported_events)) {
24518c2ecf20Sopenharmony_ci		kfree(evt);
24528c2ecf20Sopenharmony_ci		return;
24538c2ecf20Sopenharmony_ci	}
24548c2ecf20Sopenharmony_ci#endif
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci	spin_lock_irqsave(&sdev->list_lock, flags);
24578c2ecf20Sopenharmony_ci	list_add_tail(&evt->node, &sdev->event_list);
24588c2ecf20Sopenharmony_ci	schedule_work(&sdev->event_work);
24598c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&sdev->list_lock, flags);
24608c2ecf20Sopenharmony_ci}
24618c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(sdev_evt_send);
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_ci/**
24648c2ecf20Sopenharmony_ci * 	sdev_evt_alloc - allocate a new scsi event
24658c2ecf20Sopenharmony_ci *	@evt_type: type of event to allocate
24668c2ecf20Sopenharmony_ci *	@gfpflags: GFP flags for allocation
24678c2ecf20Sopenharmony_ci *
24688c2ecf20Sopenharmony_ci *	Allocates and returns a new scsi_event.
24698c2ecf20Sopenharmony_ci */
24708c2ecf20Sopenharmony_cistruct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type,
24718c2ecf20Sopenharmony_ci				  gfp_t gfpflags)
24728c2ecf20Sopenharmony_ci{
24738c2ecf20Sopenharmony_ci	struct scsi_event *evt = kzalloc(sizeof(struct scsi_event), gfpflags);
24748c2ecf20Sopenharmony_ci	if (!evt)
24758c2ecf20Sopenharmony_ci		return NULL;
24768c2ecf20Sopenharmony_ci
24778c2ecf20Sopenharmony_ci	evt->evt_type = evt_type;
24788c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&evt->node);
24798c2ecf20Sopenharmony_ci
24808c2ecf20Sopenharmony_ci	/* evt_type-specific initialization, if any */
24818c2ecf20Sopenharmony_ci	switch (evt_type) {
24828c2ecf20Sopenharmony_ci	case SDEV_EVT_MEDIA_CHANGE:
24838c2ecf20Sopenharmony_ci	case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
24848c2ecf20Sopenharmony_ci	case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
24858c2ecf20Sopenharmony_ci	case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
24868c2ecf20Sopenharmony_ci	case SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED:
24878c2ecf20Sopenharmony_ci	case SDEV_EVT_LUN_CHANGE_REPORTED:
24888c2ecf20Sopenharmony_ci	case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
24898c2ecf20Sopenharmony_ci	case SDEV_EVT_POWER_ON_RESET_OCCURRED:
24908c2ecf20Sopenharmony_ci	default:
24918c2ecf20Sopenharmony_ci		/* do nothing */
24928c2ecf20Sopenharmony_ci		break;
24938c2ecf20Sopenharmony_ci	}
24948c2ecf20Sopenharmony_ci
24958c2ecf20Sopenharmony_ci	return evt;
24968c2ecf20Sopenharmony_ci}
24978c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(sdev_evt_alloc);
24988c2ecf20Sopenharmony_ci
24998c2ecf20Sopenharmony_ci/**
25008c2ecf20Sopenharmony_ci * 	sdev_evt_send_simple - send asserted event to uevent thread
25018c2ecf20Sopenharmony_ci *	@sdev: scsi_device event occurred on
25028c2ecf20Sopenharmony_ci *	@evt_type: type of event to send
25038c2ecf20Sopenharmony_ci *	@gfpflags: GFP flags for allocation
25048c2ecf20Sopenharmony_ci *
25058c2ecf20Sopenharmony_ci *	Assert scsi device event asynchronously, given an event type.
25068c2ecf20Sopenharmony_ci */
25078c2ecf20Sopenharmony_civoid sdev_evt_send_simple(struct scsi_device *sdev,
25088c2ecf20Sopenharmony_ci			  enum scsi_device_event evt_type, gfp_t gfpflags)
25098c2ecf20Sopenharmony_ci{
25108c2ecf20Sopenharmony_ci	struct scsi_event *evt = sdev_evt_alloc(evt_type, gfpflags);
25118c2ecf20Sopenharmony_ci	if (!evt) {
25128c2ecf20Sopenharmony_ci		sdev_printk(KERN_ERR, sdev, "event %d eaten due to OOM\n",
25138c2ecf20Sopenharmony_ci			    evt_type);
25148c2ecf20Sopenharmony_ci		return;
25158c2ecf20Sopenharmony_ci	}
25168c2ecf20Sopenharmony_ci
25178c2ecf20Sopenharmony_ci	sdev_evt_send(sdev, evt);
25188c2ecf20Sopenharmony_ci}
25198c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(sdev_evt_send_simple);
25208c2ecf20Sopenharmony_ci
25218c2ecf20Sopenharmony_ci/**
25228c2ecf20Sopenharmony_ci *	scsi_device_quiesce - Block all commands except power management.
25238c2ecf20Sopenharmony_ci *	@sdev:	scsi device to quiesce.
25248c2ecf20Sopenharmony_ci *
25258c2ecf20Sopenharmony_ci *	This works by trying to transition to the SDEV_QUIESCE state
25268c2ecf20Sopenharmony_ci *	(which must be a legal transition).  When the device is in this
25278c2ecf20Sopenharmony_ci *	state, only power management requests will be accepted, all others will
25288c2ecf20Sopenharmony_ci *	be deferred.
25298c2ecf20Sopenharmony_ci *
25308c2ecf20Sopenharmony_ci *	Must be called with user context, may sleep.
25318c2ecf20Sopenharmony_ci *
25328c2ecf20Sopenharmony_ci *	Returns zero if unsuccessful or an error if not.
25338c2ecf20Sopenharmony_ci */
25348c2ecf20Sopenharmony_ciint
25358c2ecf20Sopenharmony_ciscsi_device_quiesce(struct scsi_device *sdev)
25368c2ecf20Sopenharmony_ci{
25378c2ecf20Sopenharmony_ci	struct request_queue *q = sdev->request_queue;
25388c2ecf20Sopenharmony_ci	int err;
25398c2ecf20Sopenharmony_ci
25408c2ecf20Sopenharmony_ci	/*
25418c2ecf20Sopenharmony_ci	 * It is allowed to call scsi_device_quiesce() multiple times from
25428c2ecf20Sopenharmony_ci	 * the same context but concurrent scsi_device_quiesce() calls are
25438c2ecf20Sopenharmony_ci	 * not allowed.
25448c2ecf20Sopenharmony_ci	 */
25458c2ecf20Sopenharmony_ci	WARN_ON_ONCE(sdev->quiesced_by && sdev->quiesced_by != current);
25468c2ecf20Sopenharmony_ci
25478c2ecf20Sopenharmony_ci	if (sdev->quiesced_by == current)
25488c2ecf20Sopenharmony_ci		return 0;
25498c2ecf20Sopenharmony_ci
25508c2ecf20Sopenharmony_ci	blk_set_pm_only(q);
25518c2ecf20Sopenharmony_ci
25528c2ecf20Sopenharmony_ci	blk_mq_freeze_queue(q);
25538c2ecf20Sopenharmony_ci	/*
25548c2ecf20Sopenharmony_ci	 * Ensure that the effect of blk_set_pm_only() will be visible
25558c2ecf20Sopenharmony_ci	 * for percpu_ref_tryget() callers that occur after the queue
25568c2ecf20Sopenharmony_ci	 * unfreeze even if the queue was already frozen before this function
25578c2ecf20Sopenharmony_ci	 * was called. See also https://lwn.net/Articles/573497/.
25588c2ecf20Sopenharmony_ci	 */
25598c2ecf20Sopenharmony_ci	synchronize_rcu();
25608c2ecf20Sopenharmony_ci	blk_mq_unfreeze_queue(q);
25618c2ecf20Sopenharmony_ci
25628c2ecf20Sopenharmony_ci	mutex_lock(&sdev->state_mutex);
25638c2ecf20Sopenharmony_ci	err = scsi_device_set_state(sdev, SDEV_QUIESCE);
25648c2ecf20Sopenharmony_ci	if (err == 0)
25658c2ecf20Sopenharmony_ci		sdev->quiesced_by = current;
25668c2ecf20Sopenharmony_ci	else
25678c2ecf20Sopenharmony_ci		blk_clear_pm_only(q);
25688c2ecf20Sopenharmony_ci	mutex_unlock(&sdev->state_mutex);
25698c2ecf20Sopenharmony_ci
25708c2ecf20Sopenharmony_ci	return err;
25718c2ecf20Sopenharmony_ci}
25728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_device_quiesce);
25738c2ecf20Sopenharmony_ci
25748c2ecf20Sopenharmony_ci/**
25758c2ecf20Sopenharmony_ci *	scsi_device_resume - Restart user issued commands to a quiesced device.
25768c2ecf20Sopenharmony_ci *	@sdev:	scsi device to resume.
25778c2ecf20Sopenharmony_ci *
25788c2ecf20Sopenharmony_ci *	Moves the device from quiesced back to running and restarts the
25798c2ecf20Sopenharmony_ci *	queues.
25808c2ecf20Sopenharmony_ci *
25818c2ecf20Sopenharmony_ci *	Must be called with user context, may sleep.
25828c2ecf20Sopenharmony_ci */
25838c2ecf20Sopenharmony_civoid scsi_device_resume(struct scsi_device *sdev)
25848c2ecf20Sopenharmony_ci{
25858c2ecf20Sopenharmony_ci	/* check if the device state was mutated prior to resume, and if
25868c2ecf20Sopenharmony_ci	 * so assume the state is being managed elsewhere (for example
25878c2ecf20Sopenharmony_ci	 * device deleted during suspend)
25888c2ecf20Sopenharmony_ci	 */
25898c2ecf20Sopenharmony_ci	mutex_lock(&sdev->state_mutex);
25908c2ecf20Sopenharmony_ci	if (sdev->sdev_state == SDEV_QUIESCE)
25918c2ecf20Sopenharmony_ci		scsi_device_set_state(sdev, SDEV_RUNNING);
25928c2ecf20Sopenharmony_ci	if (sdev->quiesced_by) {
25938c2ecf20Sopenharmony_ci		sdev->quiesced_by = NULL;
25948c2ecf20Sopenharmony_ci		blk_clear_pm_only(sdev->request_queue);
25958c2ecf20Sopenharmony_ci	}
25968c2ecf20Sopenharmony_ci	mutex_unlock(&sdev->state_mutex);
25978c2ecf20Sopenharmony_ci}
25988c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_device_resume);
25998c2ecf20Sopenharmony_ci
26008c2ecf20Sopenharmony_cistatic void
26018c2ecf20Sopenharmony_cidevice_quiesce_fn(struct scsi_device *sdev, void *data)
26028c2ecf20Sopenharmony_ci{
26038c2ecf20Sopenharmony_ci	scsi_device_quiesce(sdev);
26048c2ecf20Sopenharmony_ci}
26058c2ecf20Sopenharmony_ci
26068c2ecf20Sopenharmony_civoid
26078c2ecf20Sopenharmony_ciscsi_target_quiesce(struct scsi_target *starget)
26088c2ecf20Sopenharmony_ci{
26098c2ecf20Sopenharmony_ci	starget_for_each_device(starget, NULL, device_quiesce_fn);
26108c2ecf20Sopenharmony_ci}
26118c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_target_quiesce);
26128c2ecf20Sopenharmony_ci
26138c2ecf20Sopenharmony_cistatic void
26148c2ecf20Sopenharmony_cidevice_resume_fn(struct scsi_device *sdev, void *data)
26158c2ecf20Sopenharmony_ci{
26168c2ecf20Sopenharmony_ci	scsi_device_resume(sdev);
26178c2ecf20Sopenharmony_ci}
26188c2ecf20Sopenharmony_ci
26198c2ecf20Sopenharmony_civoid
26208c2ecf20Sopenharmony_ciscsi_target_resume(struct scsi_target *starget)
26218c2ecf20Sopenharmony_ci{
26228c2ecf20Sopenharmony_ci	starget_for_each_device(starget, NULL, device_resume_fn);
26238c2ecf20Sopenharmony_ci}
26248c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_target_resume);
26258c2ecf20Sopenharmony_ci
26268c2ecf20Sopenharmony_cistatic int __scsi_internal_device_block_nowait(struct scsi_device *sdev)
26278c2ecf20Sopenharmony_ci{
26288c2ecf20Sopenharmony_ci	if (scsi_device_set_state(sdev, SDEV_BLOCK))
26298c2ecf20Sopenharmony_ci		return scsi_device_set_state(sdev, SDEV_CREATED_BLOCK);
26308c2ecf20Sopenharmony_ci
26318c2ecf20Sopenharmony_ci	return 0;
26328c2ecf20Sopenharmony_ci}
26338c2ecf20Sopenharmony_ci
26348c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(sdev_queue_stop_lock);
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_civoid scsi_start_queue(struct scsi_device *sdev)
26378c2ecf20Sopenharmony_ci{
26388c2ecf20Sopenharmony_ci	bool need_start;
26398c2ecf20Sopenharmony_ci	unsigned long flags;
26408c2ecf20Sopenharmony_ci
26418c2ecf20Sopenharmony_ci	spin_lock_irqsave(&sdev_queue_stop_lock, flags);
26428c2ecf20Sopenharmony_ci	need_start = sdev->queue_stopped;
26438c2ecf20Sopenharmony_ci	sdev->queue_stopped = 0;
26448c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&sdev_queue_stop_lock, flags);
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_ci	if (need_start)
26478c2ecf20Sopenharmony_ci		blk_mq_unquiesce_queue(sdev->request_queue);
26488c2ecf20Sopenharmony_ci}
26498c2ecf20Sopenharmony_ci
26508c2ecf20Sopenharmony_cistatic void scsi_stop_queue(struct scsi_device *sdev, bool nowait)
26518c2ecf20Sopenharmony_ci{
26528c2ecf20Sopenharmony_ci	bool need_stop;
26538c2ecf20Sopenharmony_ci	unsigned long flags;
26548c2ecf20Sopenharmony_ci
26558c2ecf20Sopenharmony_ci	spin_lock_irqsave(&sdev_queue_stop_lock, flags);
26568c2ecf20Sopenharmony_ci	need_stop = !sdev->queue_stopped;
26578c2ecf20Sopenharmony_ci	sdev->queue_stopped = 1;
26588c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&sdev_queue_stop_lock, flags);
26598c2ecf20Sopenharmony_ci
26608c2ecf20Sopenharmony_ci	if (need_stop) {
26618c2ecf20Sopenharmony_ci		if (nowait)
26628c2ecf20Sopenharmony_ci			blk_mq_quiesce_queue_nowait(sdev->request_queue);
26638c2ecf20Sopenharmony_ci		else
26648c2ecf20Sopenharmony_ci			blk_mq_quiesce_queue(sdev->request_queue);
26658c2ecf20Sopenharmony_ci	}
26668c2ecf20Sopenharmony_ci}
26678c2ecf20Sopenharmony_ci
26688c2ecf20Sopenharmony_ci/**
26698c2ecf20Sopenharmony_ci * scsi_internal_device_block_nowait - try to transition to the SDEV_BLOCK state
26708c2ecf20Sopenharmony_ci * @sdev: device to block
26718c2ecf20Sopenharmony_ci *
26728c2ecf20Sopenharmony_ci * Pause SCSI command processing on the specified device. Does not sleep.
26738c2ecf20Sopenharmony_ci *
26748c2ecf20Sopenharmony_ci * Returns zero if successful or a negative error code upon failure.
26758c2ecf20Sopenharmony_ci *
26768c2ecf20Sopenharmony_ci * Notes:
26778c2ecf20Sopenharmony_ci * This routine transitions the device to the SDEV_BLOCK state (which must be
26788c2ecf20Sopenharmony_ci * a legal transition). When the device is in this state, command processing
26798c2ecf20Sopenharmony_ci * is paused until the device leaves the SDEV_BLOCK state. See also
26808c2ecf20Sopenharmony_ci * scsi_internal_device_unblock_nowait().
26818c2ecf20Sopenharmony_ci */
26828c2ecf20Sopenharmony_ciint scsi_internal_device_block_nowait(struct scsi_device *sdev)
26838c2ecf20Sopenharmony_ci{
26848c2ecf20Sopenharmony_ci	int ret = __scsi_internal_device_block_nowait(sdev);
26858c2ecf20Sopenharmony_ci
26868c2ecf20Sopenharmony_ci	/*
26878c2ecf20Sopenharmony_ci	 * The device has transitioned to SDEV_BLOCK.  Stop the
26888c2ecf20Sopenharmony_ci	 * block layer from calling the midlayer with this device's
26898c2ecf20Sopenharmony_ci	 * request queue.
26908c2ecf20Sopenharmony_ci	 */
26918c2ecf20Sopenharmony_ci	if (!ret)
26928c2ecf20Sopenharmony_ci		scsi_stop_queue(sdev, true);
26938c2ecf20Sopenharmony_ci	return ret;
26948c2ecf20Sopenharmony_ci}
26958c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait);
26968c2ecf20Sopenharmony_ci
26978c2ecf20Sopenharmony_ci/**
26988c2ecf20Sopenharmony_ci * scsi_internal_device_block - try to transition to the SDEV_BLOCK state
26998c2ecf20Sopenharmony_ci * @sdev: device to block
27008c2ecf20Sopenharmony_ci *
27018c2ecf20Sopenharmony_ci * Pause SCSI command processing on the specified device and wait until all
27028c2ecf20Sopenharmony_ci * ongoing scsi_request_fn() / scsi_queue_rq() calls have finished. May sleep.
27038c2ecf20Sopenharmony_ci *
27048c2ecf20Sopenharmony_ci * Returns zero if successful or a negative error code upon failure.
27058c2ecf20Sopenharmony_ci *
27068c2ecf20Sopenharmony_ci * Note:
27078c2ecf20Sopenharmony_ci * This routine transitions the device to the SDEV_BLOCK state (which must be
27088c2ecf20Sopenharmony_ci * a legal transition). When the device is in this state, command processing
27098c2ecf20Sopenharmony_ci * is paused until the device leaves the SDEV_BLOCK state. See also
27108c2ecf20Sopenharmony_ci * scsi_internal_device_unblock().
27118c2ecf20Sopenharmony_ci */
27128c2ecf20Sopenharmony_cistatic int scsi_internal_device_block(struct scsi_device *sdev)
27138c2ecf20Sopenharmony_ci{
27148c2ecf20Sopenharmony_ci	int err;
27158c2ecf20Sopenharmony_ci
27168c2ecf20Sopenharmony_ci	mutex_lock(&sdev->state_mutex);
27178c2ecf20Sopenharmony_ci	err = __scsi_internal_device_block_nowait(sdev);
27188c2ecf20Sopenharmony_ci	if (err == 0)
27198c2ecf20Sopenharmony_ci		scsi_stop_queue(sdev, false);
27208c2ecf20Sopenharmony_ci	mutex_unlock(&sdev->state_mutex);
27218c2ecf20Sopenharmony_ci
27228c2ecf20Sopenharmony_ci	return err;
27238c2ecf20Sopenharmony_ci}
27248c2ecf20Sopenharmony_ci
27258c2ecf20Sopenharmony_ci/**
27268c2ecf20Sopenharmony_ci * scsi_internal_device_unblock_nowait - resume a device after a block request
27278c2ecf20Sopenharmony_ci * @sdev:	device to resume
27288c2ecf20Sopenharmony_ci * @new_state:	state to set the device to after unblocking
27298c2ecf20Sopenharmony_ci *
27308c2ecf20Sopenharmony_ci * Restart the device queue for a previously suspended SCSI device. Does not
27318c2ecf20Sopenharmony_ci * sleep.
27328c2ecf20Sopenharmony_ci *
27338c2ecf20Sopenharmony_ci * Returns zero if successful or a negative error code upon failure.
27348c2ecf20Sopenharmony_ci *
27358c2ecf20Sopenharmony_ci * Notes:
27368c2ecf20Sopenharmony_ci * This routine transitions the device to the SDEV_RUNNING state or to one of
27378c2ecf20Sopenharmony_ci * the offline states (which must be a legal transition) allowing the midlayer
27388c2ecf20Sopenharmony_ci * to goose the queue for this device.
27398c2ecf20Sopenharmony_ci */
27408c2ecf20Sopenharmony_ciint scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
27418c2ecf20Sopenharmony_ci					enum scsi_device_state new_state)
27428c2ecf20Sopenharmony_ci{
27438c2ecf20Sopenharmony_ci	switch (new_state) {
27448c2ecf20Sopenharmony_ci	case SDEV_RUNNING:
27458c2ecf20Sopenharmony_ci	case SDEV_TRANSPORT_OFFLINE:
27468c2ecf20Sopenharmony_ci		break;
27478c2ecf20Sopenharmony_ci	default:
27488c2ecf20Sopenharmony_ci		return -EINVAL;
27498c2ecf20Sopenharmony_ci	}
27508c2ecf20Sopenharmony_ci
27518c2ecf20Sopenharmony_ci	/*
27528c2ecf20Sopenharmony_ci	 * Try to transition the scsi device to SDEV_RUNNING or one of the
27538c2ecf20Sopenharmony_ci	 * offlined states and goose the device queue if successful.
27548c2ecf20Sopenharmony_ci	 */
27558c2ecf20Sopenharmony_ci	switch (sdev->sdev_state) {
27568c2ecf20Sopenharmony_ci	case SDEV_BLOCK:
27578c2ecf20Sopenharmony_ci	case SDEV_TRANSPORT_OFFLINE:
27588c2ecf20Sopenharmony_ci		sdev->sdev_state = new_state;
27598c2ecf20Sopenharmony_ci		break;
27608c2ecf20Sopenharmony_ci	case SDEV_CREATED_BLOCK:
27618c2ecf20Sopenharmony_ci		if (new_state == SDEV_TRANSPORT_OFFLINE ||
27628c2ecf20Sopenharmony_ci		    new_state == SDEV_OFFLINE)
27638c2ecf20Sopenharmony_ci			sdev->sdev_state = new_state;
27648c2ecf20Sopenharmony_ci		else
27658c2ecf20Sopenharmony_ci			sdev->sdev_state = SDEV_CREATED;
27668c2ecf20Sopenharmony_ci		break;
27678c2ecf20Sopenharmony_ci	case SDEV_CANCEL:
27688c2ecf20Sopenharmony_ci	case SDEV_OFFLINE:
27698c2ecf20Sopenharmony_ci		break;
27708c2ecf20Sopenharmony_ci	default:
27718c2ecf20Sopenharmony_ci		return -EINVAL;
27728c2ecf20Sopenharmony_ci	}
27738c2ecf20Sopenharmony_ci	scsi_start_queue(sdev);
27748c2ecf20Sopenharmony_ci
27758c2ecf20Sopenharmony_ci	return 0;
27768c2ecf20Sopenharmony_ci}
27778c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_internal_device_unblock_nowait);
27788c2ecf20Sopenharmony_ci
27798c2ecf20Sopenharmony_ci/**
27808c2ecf20Sopenharmony_ci * scsi_internal_device_unblock - resume a device after a block request
27818c2ecf20Sopenharmony_ci * @sdev:	device to resume
27828c2ecf20Sopenharmony_ci * @new_state:	state to set the device to after unblocking
27838c2ecf20Sopenharmony_ci *
27848c2ecf20Sopenharmony_ci * Restart the device queue for a previously suspended SCSI device. May sleep.
27858c2ecf20Sopenharmony_ci *
27868c2ecf20Sopenharmony_ci * Returns zero if successful or a negative error code upon failure.
27878c2ecf20Sopenharmony_ci *
27888c2ecf20Sopenharmony_ci * Notes:
27898c2ecf20Sopenharmony_ci * This routine transitions the device to the SDEV_RUNNING state or to one of
27908c2ecf20Sopenharmony_ci * the offline states (which must be a legal transition) allowing the midlayer
27918c2ecf20Sopenharmony_ci * to goose the queue for this device.
27928c2ecf20Sopenharmony_ci */
27938c2ecf20Sopenharmony_cistatic int scsi_internal_device_unblock(struct scsi_device *sdev,
27948c2ecf20Sopenharmony_ci					enum scsi_device_state new_state)
27958c2ecf20Sopenharmony_ci{
27968c2ecf20Sopenharmony_ci	int ret;
27978c2ecf20Sopenharmony_ci
27988c2ecf20Sopenharmony_ci	mutex_lock(&sdev->state_mutex);
27998c2ecf20Sopenharmony_ci	ret = scsi_internal_device_unblock_nowait(sdev, new_state);
28008c2ecf20Sopenharmony_ci	mutex_unlock(&sdev->state_mutex);
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	return ret;
28038c2ecf20Sopenharmony_ci}
28048c2ecf20Sopenharmony_ci
28058c2ecf20Sopenharmony_cistatic void
28068c2ecf20Sopenharmony_cidevice_block(struct scsi_device *sdev, void *data)
28078c2ecf20Sopenharmony_ci{
28088c2ecf20Sopenharmony_ci	int ret;
28098c2ecf20Sopenharmony_ci
28108c2ecf20Sopenharmony_ci	ret = scsi_internal_device_block(sdev);
28118c2ecf20Sopenharmony_ci
28128c2ecf20Sopenharmony_ci	WARN_ONCE(ret, "scsi_internal_device_block(%s) failed: ret = %d\n",
28138c2ecf20Sopenharmony_ci		  dev_name(&sdev->sdev_gendev), ret);
28148c2ecf20Sopenharmony_ci}
28158c2ecf20Sopenharmony_ci
28168c2ecf20Sopenharmony_cistatic int
28178c2ecf20Sopenharmony_citarget_block(struct device *dev, void *data)
28188c2ecf20Sopenharmony_ci{
28198c2ecf20Sopenharmony_ci	if (scsi_is_target_device(dev))
28208c2ecf20Sopenharmony_ci		starget_for_each_device(to_scsi_target(dev), NULL,
28218c2ecf20Sopenharmony_ci					device_block);
28228c2ecf20Sopenharmony_ci	return 0;
28238c2ecf20Sopenharmony_ci}
28248c2ecf20Sopenharmony_ci
28258c2ecf20Sopenharmony_civoid
28268c2ecf20Sopenharmony_ciscsi_target_block(struct device *dev)
28278c2ecf20Sopenharmony_ci{
28288c2ecf20Sopenharmony_ci	if (scsi_is_target_device(dev))
28298c2ecf20Sopenharmony_ci		starget_for_each_device(to_scsi_target(dev), NULL,
28308c2ecf20Sopenharmony_ci					device_block);
28318c2ecf20Sopenharmony_ci	else
28328c2ecf20Sopenharmony_ci		device_for_each_child(dev, NULL, target_block);
28338c2ecf20Sopenharmony_ci}
28348c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_target_block);
28358c2ecf20Sopenharmony_ci
28368c2ecf20Sopenharmony_cistatic void
28378c2ecf20Sopenharmony_cidevice_unblock(struct scsi_device *sdev, void *data)
28388c2ecf20Sopenharmony_ci{
28398c2ecf20Sopenharmony_ci	scsi_internal_device_unblock(sdev, *(enum scsi_device_state *)data);
28408c2ecf20Sopenharmony_ci}
28418c2ecf20Sopenharmony_ci
28428c2ecf20Sopenharmony_cistatic int
28438c2ecf20Sopenharmony_citarget_unblock(struct device *dev, void *data)
28448c2ecf20Sopenharmony_ci{
28458c2ecf20Sopenharmony_ci	if (scsi_is_target_device(dev))
28468c2ecf20Sopenharmony_ci		starget_for_each_device(to_scsi_target(dev), data,
28478c2ecf20Sopenharmony_ci					device_unblock);
28488c2ecf20Sopenharmony_ci	return 0;
28498c2ecf20Sopenharmony_ci}
28508c2ecf20Sopenharmony_ci
28518c2ecf20Sopenharmony_civoid
28528c2ecf20Sopenharmony_ciscsi_target_unblock(struct device *dev, enum scsi_device_state new_state)
28538c2ecf20Sopenharmony_ci{
28548c2ecf20Sopenharmony_ci	if (scsi_is_target_device(dev))
28558c2ecf20Sopenharmony_ci		starget_for_each_device(to_scsi_target(dev), &new_state,
28568c2ecf20Sopenharmony_ci					device_unblock);
28578c2ecf20Sopenharmony_ci	else
28588c2ecf20Sopenharmony_ci		device_for_each_child(dev, &new_state, target_unblock);
28598c2ecf20Sopenharmony_ci}
28608c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_target_unblock);
28618c2ecf20Sopenharmony_ci
28628c2ecf20Sopenharmony_ciint
28638c2ecf20Sopenharmony_ciscsi_host_block(struct Scsi_Host *shost)
28648c2ecf20Sopenharmony_ci{
28658c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
28668c2ecf20Sopenharmony_ci	int ret = 0;
28678c2ecf20Sopenharmony_ci
28688c2ecf20Sopenharmony_ci	/*
28698c2ecf20Sopenharmony_ci	 * Call scsi_internal_device_block_nowait so we can avoid
28708c2ecf20Sopenharmony_ci	 * calling synchronize_rcu() for each LUN.
28718c2ecf20Sopenharmony_ci	 */
28728c2ecf20Sopenharmony_ci	shost_for_each_device(sdev, shost) {
28738c2ecf20Sopenharmony_ci		mutex_lock(&sdev->state_mutex);
28748c2ecf20Sopenharmony_ci		ret = scsi_internal_device_block_nowait(sdev);
28758c2ecf20Sopenharmony_ci		mutex_unlock(&sdev->state_mutex);
28768c2ecf20Sopenharmony_ci		if (ret) {
28778c2ecf20Sopenharmony_ci			scsi_device_put(sdev);
28788c2ecf20Sopenharmony_ci			break;
28798c2ecf20Sopenharmony_ci		}
28808c2ecf20Sopenharmony_ci	}
28818c2ecf20Sopenharmony_ci
28828c2ecf20Sopenharmony_ci	/*
28838c2ecf20Sopenharmony_ci	 * SCSI never enables blk-mq's BLK_MQ_F_BLOCKING flag so
28848c2ecf20Sopenharmony_ci	 * calling synchronize_rcu() once is enough.
28858c2ecf20Sopenharmony_ci	 */
28868c2ecf20Sopenharmony_ci	WARN_ON_ONCE(shost->tag_set.flags & BLK_MQ_F_BLOCKING);
28878c2ecf20Sopenharmony_ci
28888c2ecf20Sopenharmony_ci	if (!ret)
28898c2ecf20Sopenharmony_ci		synchronize_rcu();
28908c2ecf20Sopenharmony_ci
28918c2ecf20Sopenharmony_ci	return ret;
28928c2ecf20Sopenharmony_ci}
28938c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_host_block);
28948c2ecf20Sopenharmony_ci
28958c2ecf20Sopenharmony_ciint
28968c2ecf20Sopenharmony_ciscsi_host_unblock(struct Scsi_Host *shost, int new_state)
28978c2ecf20Sopenharmony_ci{
28988c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
28998c2ecf20Sopenharmony_ci	int ret = 0;
29008c2ecf20Sopenharmony_ci
29018c2ecf20Sopenharmony_ci	shost_for_each_device(sdev, shost) {
29028c2ecf20Sopenharmony_ci		ret = scsi_internal_device_unblock(sdev, new_state);
29038c2ecf20Sopenharmony_ci		if (ret) {
29048c2ecf20Sopenharmony_ci			scsi_device_put(sdev);
29058c2ecf20Sopenharmony_ci			break;
29068c2ecf20Sopenharmony_ci		}
29078c2ecf20Sopenharmony_ci	}
29088c2ecf20Sopenharmony_ci	return ret;
29098c2ecf20Sopenharmony_ci}
29108c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(scsi_host_unblock);
29118c2ecf20Sopenharmony_ci
29128c2ecf20Sopenharmony_ci/**
29138c2ecf20Sopenharmony_ci * scsi_kmap_atomic_sg - find and atomically map an sg-elemnt
29148c2ecf20Sopenharmony_ci * @sgl:	scatter-gather list
29158c2ecf20Sopenharmony_ci * @sg_count:	number of segments in sg
29168c2ecf20Sopenharmony_ci * @offset:	offset in bytes into sg, on return offset into the mapped area
29178c2ecf20Sopenharmony_ci * @len:	bytes to map, on return number of bytes mapped
29188c2ecf20Sopenharmony_ci *
29198c2ecf20Sopenharmony_ci * Returns virtual address of the start of the mapped page
29208c2ecf20Sopenharmony_ci */
29218c2ecf20Sopenharmony_civoid *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
29228c2ecf20Sopenharmony_ci			  size_t *offset, size_t *len)
29238c2ecf20Sopenharmony_ci{
29248c2ecf20Sopenharmony_ci	int i;
29258c2ecf20Sopenharmony_ci	size_t sg_len = 0, len_complete = 0;
29268c2ecf20Sopenharmony_ci	struct scatterlist *sg;
29278c2ecf20Sopenharmony_ci	struct page *page;
29288c2ecf20Sopenharmony_ci
29298c2ecf20Sopenharmony_ci	WARN_ON(!irqs_disabled());
29308c2ecf20Sopenharmony_ci
29318c2ecf20Sopenharmony_ci	for_each_sg(sgl, sg, sg_count, i) {
29328c2ecf20Sopenharmony_ci		len_complete = sg_len; /* Complete sg-entries */
29338c2ecf20Sopenharmony_ci		sg_len += sg->length;
29348c2ecf20Sopenharmony_ci		if (sg_len > *offset)
29358c2ecf20Sopenharmony_ci			break;
29368c2ecf20Sopenharmony_ci	}
29378c2ecf20Sopenharmony_ci
29388c2ecf20Sopenharmony_ci	if (unlikely(i == sg_count)) {
29398c2ecf20Sopenharmony_ci		printk(KERN_ERR "%s: Bytes in sg: %zu, requested offset %zu, "
29408c2ecf20Sopenharmony_ci			"elements %d\n",
29418c2ecf20Sopenharmony_ci		       __func__, sg_len, *offset, sg_count);
29428c2ecf20Sopenharmony_ci		WARN_ON(1);
29438c2ecf20Sopenharmony_ci		return NULL;
29448c2ecf20Sopenharmony_ci	}
29458c2ecf20Sopenharmony_ci
29468c2ecf20Sopenharmony_ci	/* Offset starting from the beginning of first page in this sg-entry */
29478c2ecf20Sopenharmony_ci	*offset = *offset - len_complete + sg->offset;
29488c2ecf20Sopenharmony_ci
29498c2ecf20Sopenharmony_ci	/* Assumption: contiguous pages can be accessed as "page + i" */
29508c2ecf20Sopenharmony_ci	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
29518c2ecf20Sopenharmony_ci	*offset &= ~PAGE_MASK;
29528c2ecf20Sopenharmony_ci
29538c2ecf20Sopenharmony_ci	/* Bytes in this sg-entry from *offset to the end of the page */
29548c2ecf20Sopenharmony_ci	sg_len = PAGE_SIZE - *offset;
29558c2ecf20Sopenharmony_ci	if (*len > sg_len)
29568c2ecf20Sopenharmony_ci		*len = sg_len;
29578c2ecf20Sopenharmony_ci
29588c2ecf20Sopenharmony_ci	return kmap_atomic(page);
29598c2ecf20Sopenharmony_ci}
29608c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_kmap_atomic_sg);
29618c2ecf20Sopenharmony_ci
29628c2ecf20Sopenharmony_ci/**
29638c2ecf20Sopenharmony_ci * scsi_kunmap_atomic_sg - atomically unmap a virtual address, previously mapped with scsi_kmap_atomic_sg
29648c2ecf20Sopenharmony_ci * @virt:	virtual address to be unmapped
29658c2ecf20Sopenharmony_ci */
29668c2ecf20Sopenharmony_civoid scsi_kunmap_atomic_sg(void *virt)
29678c2ecf20Sopenharmony_ci{
29688c2ecf20Sopenharmony_ci	kunmap_atomic(virt);
29698c2ecf20Sopenharmony_ci}
29708c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_kunmap_atomic_sg);
29718c2ecf20Sopenharmony_ci
29728c2ecf20Sopenharmony_civoid sdev_disable_disk_events(struct scsi_device *sdev)
29738c2ecf20Sopenharmony_ci{
29748c2ecf20Sopenharmony_ci	atomic_inc(&sdev->disk_events_disable_depth);
29758c2ecf20Sopenharmony_ci}
29768c2ecf20Sopenharmony_ciEXPORT_SYMBOL(sdev_disable_disk_events);
29778c2ecf20Sopenharmony_ci
29788c2ecf20Sopenharmony_civoid sdev_enable_disk_events(struct scsi_device *sdev)
29798c2ecf20Sopenharmony_ci{
29808c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(atomic_read(&sdev->disk_events_disable_depth) <= 0))
29818c2ecf20Sopenharmony_ci		return;
29828c2ecf20Sopenharmony_ci	atomic_dec(&sdev->disk_events_disable_depth);
29838c2ecf20Sopenharmony_ci}
29848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(sdev_enable_disk_events);
29858c2ecf20Sopenharmony_ci
29868c2ecf20Sopenharmony_cistatic unsigned char designator_prio(const unsigned char *d)
29878c2ecf20Sopenharmony_ci{
29888c2ecf20Sopenharmony_ci	if (d[1] & 0x30)
29898c2ecf20Sopenharmony_ci		/* not associated with LUN */
29908c2ecf20Sopenharmony_ci		return 0;
29918c2ecf20Sopenharmony_ci
29928c2ecf20Sopenharmony_ci	if (d[3] == 0)
29938c2ecf20Sopenharmony_ci		/* invalid length */
29948c2ecf20Sopenharmony_ci		return 0;
29958c2ecf20Sopenharmony_ci
29968c2ecf20Sopenharmony_ci	/*
29978c2ecf20Sopenharmony_ci	 * Order of preference for lun descriptor:
29988c2ecf20Sopenharmony_ci	 * - SCSI name string
29998c2ecf20Sopenharmony_ci	 * - NAA IEEE Registered Extended
30008c2ecf20Sopenharmony_ci	 * - EUI-64 based 16-byte
30018c2ecf20Sopenharmony_ci	 * - EUI-64 based 12-byte
30028c2ecf20Sopenharmony_ci	 * - NAA IEEE Registered
30038c2ecf20Sopenharmony_ci	 * - NAA IEEE Extended
30048c2ecf20Sopenharmony_ci	 * - EUI-64 based 8-byte
30058c2ecf20Sopenharmony_ci	 * - SCSI name string (truncated)
30068c2ecf20Sopenharmony_ci	 * - T10 Vendor ID
30078c2ecf20Sopenharmony_ci	 * as longer descriptors reduce the likelyhood
30088c2ecf20Sopenharmony_ci	 * of identification clashes.
30098c2ecf20Sopenharmony_ci	 */
30108c2ecf20Sopenharmony_ci
30118c2ecf20Sopenharmony_ci	switch (d[1] & 0xf) {
30128c2ecf20Sopenharmony_ci	case 8:
30138c2ecf20Sopenharmony_ci		/* SCSI name string, variable-length UTF-8 */
30148c2ecf20Sopenharmony_ci		return 9;
30158c2ecf20Sopenharmony_ci	case 3:
30168c2ecf20Sopenharmony_ci		switch (d[4] >> 4) {
30178c2ecf20Sopenharmony_ci		case 6:
30188c2ecf20Sopenharmony_ci			/* NAA registered extended */
30198c2ecf20Sopenharmony_ci			return 8;
30208c2ecf20Sopenharmony_ci		case 5:
30218c2ecf20Sopenharmony_ci			/* NAA registered */
30228c2ecf20Sopenharmony_ci			return 5;
30238c2ecf20Sopenharmony_ci		case 4:
30248c2ecf20Sopenharmony_ci			/* NAA extended */
30258c2ecf20Sopenharmony_ci			return 4;
30268c2ecf20Sopenharmony_ci		case 3:
30278c2ecf20Sopenharmony_ci			/* NAA locally assigned */
30288c2ecf20Sopenharmony_ci			return 1;
30298c2ecf20Sopenharmony_ci		default:
30308c2ecf20Sopenharmony_ci			break;
30318c2ecf20Sopenharmony_ci		}
30328c2ecf20Sopenharmony_ci		break;
30338c2ecf20Sopenharmony_ci	case 2:
30348c2ecf20Sopenharmony_ci		switch (d[3]) {
30358c2ecf20Sopenharmony_ci		case 16:
30368c2ecf20Sopenharmony_ci			/* EUI64-based, 16 byte */
30378c2ecf20Sopenharmony_ci			return 7;
30388c2ecf20Sopenharmony_ci		case 12:
30398c2ecf20Sopenharmony_ci			/* EUI64-based, 12 byte */
30408c2ecf20Sopenharmony_ci			return 6;
30418c2ecf20Sopenharmony_ci		case 8:
30428c2ecf20Sopenharmony_ci			/* EUI64-based, 8 byte */
30438c2ecf20Sopenharmony_ci			return 3;
30448c2ecf20Sopenharmony_ci		default:
30458c2ecf20Sopenharmony_ci			break;
30468c2ecf20Sopenharmony_ci		}
30478c2ecf20Sopenharmony_ci		break;
30488c2ecf20Sopenharmony_ci	case 1:
30498c2ecf20Sopenharmony_ci		/* T10 vendor ID */
30508c2ecf20Sopenharmony_ci		return 1;
30518c2ecf20Sopenharmony_ci	default:
30528c2ecf20Sopenharmony_ci		break;
30538c2ecf20Sopenharmony_ci	}
30548c2ecf20Sopenharmony_ci
30558c2ecf20Sopenharmony_ci	return 0;
30568c2ecf20Sopenharmony_ci}
30578c2ecf20Sopenharmony_ci
30588c2ecf20Sopenharmony_ci/**
30598c2ecf20Sopenharmony_ci * scsi_vpd_lun_id - return a unique device identification
30608c2ecf20Sopenharmony_ci * @sdev: SCSI device
30618c2ecf20Sopenharmony_ci * @id:   buffer for the identification
30628c2ecf20Sopenharmony_ci * @id_len:  length of the buffer
30638c2ecf20Sopenharmony_ci *
30648c2ecf20Sopenharmony_ci * Copies a unique device identification into @id based
30658c2ecf20Sopenharmony_ci * on the information in the VPD page 0x83 of the device.
30668c2ecf20Sopenharmony_ci * The string will be formatted as a SCSI name string.
30678c2ecf20Sopenharmony_ci *
30688c2ecf20Sopenharmony_ci * Returns the length of the identification or error on failure.
30698c2ecf20Sopenharmony_ci * If the identifier is longer than the supplied buffer the actual
30708c2ecf20Sopenharmony_ci * identifier length is returned and the buffer is not zero-padded.
30718c2ecf20Sopenharmony_ci */
30728c2ecf20Sopenharmony_ciint scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len)
30738c2ecf20Sopenharmony_ci{
30748c2ecf20Sopenharmony_ci	u8 cur_id_prio = 0;
30758c2ecf20Sopenharmony_ci	u8 cur_id_size = 0;
30768c2ecf20Sopenharmony_ci	const unsigned char *d, *cur_id_str;
30778c2ecf20Sopenharmony_ci	const struct scsi_vpd *vpd_pg83;
30788c2ecf20Sopenharmony_ci	int id_size = -EINVAL;
30798c2ecf20Sopenharmony_ci
30808c2ecf20Sopenharmony_ci	rcu_read_lock();
30818c2ecf20Sopenharmony_ci	vpd_pg83 = rcu_dereference(sdev->vpd_pg83);
30828c2ecf20Sopenharmony_ci	if (!vpd_pg83) {
30838c2ecf20Sopenharmony_ci		rcu_read_unlock();
30848c2ecf20Sopenharmony_ci		return -ENXIO;
30858c2ecf20Sopenharmony_ci	}
30868c2ecf20Sopenharmony_ci
30878c2ecf20Sopenharmony_ci	/* The id string must be at least 20 bytes + terminating NULL byte */
30888c2ecf20Sopenharmony_ci	if (id_len < 21) {
30898c2ecf20Sopenharmony_ci		rcu_read_unlock();
30908c2ecf20Sopenharmony_ci		return -EINVAL;
30918c2ecf20Sopenharmony_ci	}
30928c2ecf20Sopenharmony_ci
30938c2ecf20Sopenharmony_ci	memset(id, 0, id_len);
30948c2ecf20Sopenharmony_ci	d = vpd_pg83->data + 4;
30958c2ecf20Sopenharmony_ci	while (d < vpd_pg83->data + vpd_pg83->len) {
30968c2ecf20Sopenharmony_ci		u8 prio = designator_prio(d);
30978c2ecf20Sopenharmony_ci
30988c2ecf20Sopenharmony_ci		if (prio == 0 || cur_id_prio > prio)
30998c2ecf20Sopenharmony_ci			goto next_desig;
31008c2ecf20Sopenharmony_ci
31018c2ecf20Sopenharmony_ci		switch (d[1] & 0xf) {
31028c2ecf20Sopenharmony_ci		case 0x1:
31038c2ecf20Sopenharmony_ci			/* T10 Vendor ID */
31048c2ecf20Sopenharmony_ci			if (cur_id_size > d[3])
31058c2ecf20Sopenharmony_ci				break;
31068c2ecf20Sopenharmony_ci			cur_id_prio = prio;
31078c2ecf20Sopenharmony_ci			cur_id_size = d[3];
31088c2ecf20Sopenharmony_ci			if (cur_id_size + 4 > id_len)
31098c2ecf20Sopenharmony_ci				cur_id_size = id_len - 4;
31108c2ecf20Sopenharmony_ci			cur_id_str = d + 4;
31118c2ecf20Sopenharmony_ci			id_size = snprintf(id, id_len, "t10.%*pE",
31128c2ecf20Sopenharmony_ci					   cur_id_size, cur_id_str);
31138c2ecf20Sopenharmony_ci			break;
31148c2ecf20Sopenharmony_ci		case 0x2:
31158c2ecf20Sopenharmony_ci			/* EUI-64 */
31168c2ecf20Sopenharmony_ci			cur_id_prio = prio;
31178c2ecf20Sopenharmony_ci			cur_id_size = d[3];
31188c2ecf20Sopenharmony_ci			cur_id_str = d + 4;
31198c2ecf20Sopenharmony_ci			switch (cur_id_size) {
31208c2ecf20Sopenharmony_ci			case 8:
31218c2ecf20Sopenharmony_ci				id_size = snprintf(id, id_len,
31228c2ecf20Sopenharmony_ci						   "eui.%8phN",
31238c2ecf20Sopenharmony_ci						   cur_id_str);
31248c2ecf20Sopenharmony_ci				break;
31258c2ecf20Sopenharmony_ci			case 12:
31268c2ecf20Sopenharmony_ci				id_size = snprintf(id, id_len,
31278c2ecf20Sopenharmony_ci						   "eui.%12phN",
31288c2ecf20Sopenharmony_ci						   cur_id_str);
31298c2ecf20Sopenharmony_ci				break;
31308c2ecf20Sopenharmony_ci			case 16:
31318c2ecf20Sopenharmony_ci				id_size = snprintf(id, id_len,
31328c2ecf20Sopenharmony_ci						   "eui.%16phN",
31338c2ecf20Sopenharmony_ci						   cur_id_str);
31348c2ecf20Sopenharmony_ci				break;
31358c2ecf20Sopenharmony_ci			default:
31368c2ecf20Sopenharmony_ci				break;
31378c2ecf20Sopenharmony_ci			}
31388c2ecf20Sopenharmony_ci			break;
31398c2ecf20Sopenharmony_ci		case 0x3:
31408c2ecf20Sopenharmony_ci			/* NAA */
31418c2ecf20Sopenharmony_ci			cur_id_prio = prio;
31428c2ecf20Sopenharmony_ci			cur_id_size = d[3];
31438c2ecf20Sopenharmony_ci			cur_id_str = d + 4;
31448c2ecf20Sopenharmony_ci			switch (cur_id_size) {
31458c2ecf20Sopenharmony_ci			case 8:
31468c2ecf20Sopenharmony_ci				id_size = snprintf(id, id_len,
31478c2ecf20Sopenharmony_ci						   "naa.%8phN",
31488c2ecf20Sopenharmony_ci						   cur_id_str);
31498c2ecf20Sopenharmony_ci				break;
31508c2ecf20Sopenharmony_ci			case 16:
31518c2ecf20Sopenharmony_ci				id_size = snprintf(id, id_len,
31528c2ecf20Sopenharmony_ci						   "naa.%16phN",
31538c2ecf20Sopenharmony_ci						   cur_id_str);
31548c2ecf20Sopenharmony_ci				break;
31558c2ecf20Sopenharmony_ci			default:
31568c2ecf20Sopenharmony_ci				break;
31578c2ecf20Sopenharmony_ci			}
31588c2ecf20Sopenharmony_ci			break;
31598c2ecf20Sopenharmony_ci		case 0x8:
31608c2ecf20Sopenharmony_ci			/* SCSI name string */
31618c2ecf20Sopenharmony_ci			if (cur_id_size > d[3])
31628c2ecf20Sopenharmony_ci				break;
31638c2ecf20Sopenharmony_ci			/* Prefer others for truncated descriptor */
31648c2ecf20Sopenharmony_ci			if (d[3] > id_len) {
31658c2ecf20Sopenharmony_ci				prio = 2;
31668c2ecf20Sopenharmony_ci				if (cur_id_prio > prio)
31678c2ecf20Sopenharmony_ci					break;
31688c2ecf20Sopenharmony_ci			}
31698c2ecf20Sopenharmony_ci			cur_id_prio = prio;
31708c2ecf20Sopenharmony_ci			cur_id_size = id_size = d[3];
31718c2ecf20Sopenharmony_ci			cur_id_str = d + 4;
31728c2ecf20Sopenharmony_ci			if (cur_id_size >= id_len)
31738c2ecf20Sopenharmony_ci				cur_id_size = id_len - 1;
31748c2ecf20Sopenharmony_ci			memcpy(id, cur_id_str, cur_id_size);
31758c2ecf20Sopenharmony_ci			break;
31768c2ecf20Sopenharmony_ci		default:
31778c2ecf20Sopenharmony_ci			break;
31788c2ecf20Sopenharmony_ci		}
31798c2ecf20Sopenharmony_cinext_desig:
31808c2ecf20Sopenharmony_ci		d += d[3] + 4;
31818c2ecf20Sopenharmony_ci	}
31828c2ecf20Sopenharmony_ci	rcu_read_unlock();
31838c2ecf20Sopenharmony_ci
31848c2ecf20Sopenharmony_ci	return id_size;
31858c2ecf20Sopenharmony_ci}
31868c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_vpd_lun_id);
31878c2ecf20Sopenharmony_ci
31888c2ecf20Sopenharmony_ci/*
31898c2ecf20Sopenharmony_ci * scsi_vpd_tpg_id - return a target port group identifier
31908c2ecf20Sopenharmony_ci * @sdev: SCSI device
31918c2ecf20Sopenharmony_ci *
31928c2ecf20Sopenharmony_ci * Returns the Target Port Group identifier from the information
31938c2ecf20Sopenharmony_ci * froom VPD page 0x83 of the device.
31948c2ecf20Sopenharmony_ci *
31958c2ecf20Sopenharmony_ci * Returns the identifier or error on failure.
31968c2ecf20Sopenharmony_ci */
31978c2ecf20Sopenharmony_ciint scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)
31988c2ecf20Sopenharmony_ci{
31998c2ecf20Sopenharmony_ci	const unsigned char *d;
32008c2ecf20Sopenharmony_ci	const struct scsi_vpd *vpd_pg83;
32018c2ecf20Sopenharmony_ci	int group_id = -EAGAIN, rel_port = -1;
32028c2ecf20Sopenharmony_ci
32038c2ecf20Sopenharmony_ci	rcu_read_lock();
32048c2ecf20Sopenharmony_ci	vpd_pg83 = rcu_dereference(sdev->vpd_pg83);
32058c2ecf20Sopenharmony_ci	if (!vpd_pg83) {
32068c2ecf20Sopenharmony_ci		rcu_read_unlock();
32078c2ecf20Sopenharmony_ci		return -ENXIO;
32088c2ecf20Sopenharmony_ci	}
32098c2ecf20Sopenharmony_ci
32108c2ecf20Sopenharmony_ci	d = vpd_pg83->data + 4;
32118c2ecf20Sopenharmony_ci	while (d < vpd_pg83->data + vpd_pg83->len) {
32128c2ecf20Sopenharmony_ci		switch (d[1] & 0xf) {
32138c2ecf20Sopenharmony_ci		case 0x4:
32148c2ecf20Sopenharmony_ci			/* Relative target port */
32158c2ecf20Sopenharmony_ci			rel_port = get_unaligned_be16(&d[6]);
32168c2ecf20Sopenharmony_ci			break;
32178c2ecf20Sopenharmony_ci		case 0x5:
32188c2ecf20Sopenharmony_ci			/* Target port group */
32198c2ecf20Sopenharmony_ci			group_id = get_unaligned_be16(&d[6]);
32208c2ecf20Sopenharmony_ci			break;
32218c2ecf20Sopenharmony_ci		default:
32228c2ecf20Sopenharmony_ci			break;
32238c2ecf20Sopenharmony_ci		}
32248c2ecf20Sopenharmony_ci		d += d[3] + 4;
32258c2ecf20Sopenharmony_ci	}
32268c2ecf20Sopenharmony_ci	rcu_read_unlock();
32278c2ecf20Sopenharmony_ci
32288c2ecf20Sopenharmony_ci	if (group_id >= 0 && rel_id && rel_port != -1)
32298c2ecf20Sopenharmony_ci		*rel_id = rel_port;
32308c2ecf20Sopenharmony_ci
32318c2ecf20Sopenharmony_ci	return group_id;
32328c2ecf20Sopenharmony_ci}
32338c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_vpd_tpg_id);
3234