diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 1562 |
1 files changed, 881 insertions, 681 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 610ee41fa54c..8b89fab7c420 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -21,6 +21,7 @@ #include <linux/hardirq.h> #include <linux/scatterlist.h> #include <linux/blk-mq.h> +#include <linux/blk-integrity.h> #include <linux/ratelimit.h> #include <asm/unaligned.h> @@ -52,51 +53,17 @@ #define SCSI_INLINE_SG_CNT 2 #endif -static struct kmem_cache *scsi_sdb_cache; static struct kmem_cache *scsi_sense_cache; -static struct kmem_cache *scsi_sense_isadma_cache; static DEFINE_MUTEX(scsi_sense_cache_mutex); static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd); -static inline struct kmem_cache * -scsi_select_sense_cache(bool unchecked_isa_dma) -{ - return unchecked_isa_dma ? scsi_sense_isadma_cache : scsi_sense_cache; -} - -static void scsi_free_sense_buffer(bool unchecked_isa_dma, - unsigned char *sense_buffer) -{ - kmem_cache_free(scsi_select_sense_cache(unchecked_isa_dma), - sense_buffer); -} - -static unsigned char *scsi_alloc_sense_buffer(bool unchecked_isa_dma, - gfp_t gfp_mask, int numa_node) -{ - return kmem_cache_alloc_node(scsi_select_sense_cache(unchecked_isa_dma), - gfp_mask, numa_node); -} - int scsi_init_sense_cache(struct Scsi_Host *shost) { - struct kmem_cache *cache; int ret = 0; mutex_lock(&scsi_sense_cache_mutex); - cache = scsi_select_sense_cache(shost->unchecked_isa_dma); - if (cache) - goto exit; - - if (shost->unchecked_isa_dma) { - scsi_sense_isadma_cache = - kmem_cache_create("scsi_sense_cache(DMA)", - SCSI_SENSE_BUFFERSIZE, 0, - SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA, NULL); - if (!scsi_sense_isadma_cache) - ret = -ENOMEM; - } else { + if (!scsi_sense_cache) { scsi_sense_cache = kmem_cache_create_usercopy("scsi_sense_cache", SCSI_SENSE_BUFFERSIZE, 0, SLAB_HWCACHE_ALIGN, @@ -104,18 +71,10 @@ int scsi_init_sense_cache(struct Scsi_Host *shost) if (!scsi_sense_cache) ret = -ENOMEM; } - exit: mutex_unlock(&scsi_sense_cache_mutex); return ret; } -/* - * When to reinvoke queueing after a resource shortage. It's 3 msecs to - * not change behaviour from the previous unplug mechanism, experimentation - * may prove this needs changing. - */ -#define SCSI_QUEUE_DELAY 3 - static void scsi_set_blocked(struct scsi_cmnd *cmd, int reason) { @@ -152,15 +111,22 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason) } } -static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) +static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd, unsigned long msecs) { - if (cmd->request->rq_flags & RQF_DONTPREP) { - cmd->request->rq_flags &= ~RQF_DONTPREP; + struct request *rq = scsi_cmd_to_rq(cmd); + + if (rq->rq_flags & RQF_DONTPREP) { + rq->rq_flags &= ~RQF_DONTPREP; scsi_mq_uninit_cmd(cmd); } else { WARN_ON_ONCE(true); } - blk_mq_requeue_request(cmd->request, true); + + if (msecs) { + blk_mq_requeue_request(rq, false); + blk_mq_delay_kick_requeue_list(rq->q, msecs); + } else + blk_mq_requeue_request(rq, true); } /** @@ -195,31 +161,24 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) * Requeue this command. It will go before all other commands * that are already in the queue. Schedule requeue work under * lock such that the kblockd_schedule_work() call happens - * before blk_cleanup_queue() finishes. + * before blk_mq_destroy_queue() finishes. */ cmd->result = 0; - blk_mq_requeue_request(cmd->request, true); + blk_mq_requeue_request(scsi_cmd_to_rq(cmd), true); } -/* - * Function: scsi_queue_insert() - * - * Purpose: Insert a command in the midlevel queue. - * - * Arguments: cmd - command that we are adding to queue. - * reason - why we are inserting command to queue. - * - * Lock status: Assumed that lock is not held upon entry. +/** + * scsi_queue_insert - Reinsert a command in the queue. + * @cmd: command that we are adding to queue. + * @reason: why we are inserting command to queue. * - * Returns: Nothing. + * We do this for one of two cases. Either the host is busy and it cannot accept + * any more commands for the time being, or the device returned QUEUE_FULL and + * can accept no more commands. * - * Notes: We do this for one of two cases. Either the host is busy - * and it cannot accept any more commands for the time being, - * or the device returned QUEUE_FULL and can accept no more - * commands. - * Notes: This could be called either from an interrupt context or a - * normal process context. + * Context: This could be called either from an interrupt context or a normal + * process context. */ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) { @@ -236,7 +195,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) * @bufflen: len of buffer * @sense: optional sense buffer * @sshdr: optional decoded sense header - * @timeout: request timeout in seconds + * @timeout: request timeout in HZ * @retries: number of times to retry request * @flags: flags for ->cmd_flags * @rq_flags: flags for ->rq_flags @@ -248,27 +207,30 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, struct scsi_sense_hdr *sshdr, - int timeout, int retries, u64 flags, req_flags_t rq_flags, - int *resid) + int timeout, int retries, blk_opf_t flags, + req_flags_t rq_flags, int *resid) { struct request *req; - struct scsi_request *rq; - int ret = DRIVER_ERROR << 24; + struct scsi_cmnd *scmd; + int ret; - req = blk_get_request(sdev->request_queue, + req = scsi_alloc_request(sdev->request_queue, data_direction == DMA_TO_DEVICE ? - REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT); + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, + rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); if (IS_ERR(req)) - return ret; - rq = scsi_req(req); - - if (bufflen && blk_rq_map_kern(sdev->request_queue, req, - buffer, bufflen, GFP_NOIO)) - goto out; - - rq->cmd_len = COMMAND_SIZE(cmd[0]); - memcpy(rq->cmd, cmd, rq->cmd_len); - rq->retries = retries; + return PTR_ERR(req); + + if (bufflen) { + ret = blk_rq_map_kern(sdev->request_queue, req, + buffer, bufflen, GFP_NOIO); + if (ret) + goto out; + } + scmd = blk_mq_rq_to_pdu(req); + scmd->cmd_len = COMMAND_SIZE(cmd[0]); + memcpy(scmd->cmnd, cmd, scmd->cmd_len); + scmd->allowed = retries; req->timeout = timeout; req->cmd_flags |= flags; req->rq_flags |= rq_flags | RQF_QUIET; @@ -276,7 +238,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, /* * head injection *required* here otherwise quiesce won't work */ - blk_execute_rq(req->q, NULL, req, 1); + blk_execute_rq(req, true); /* * Some devices (USB mass-storage in particular) may transfer @@ -284,43 +246,25 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, * is invalid. Prevent the garbage from being misinterpreted * and prevent security leaks by zeroing out the excess data. */ - if (unlikely(rq->resid_len > 0 && rq->resid_len <= bufflen)) - memset(buffer + (bufflen - rq->resid_len), 0, rq->resid_len); + if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) + memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); if (resid) - *resid = rq->resid_len; - if (sense && rq->sense_len) - memcpy(sense, rq->sense, SCSI_SENSE_BUFFERSIZE); + *resid = scmd->resid_len; + if (sense && scmd->sense_len) + memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); if (sshdr) - scsi_normalize_sense(rq->sense, rq->sense_len, sshdr); - ret = rq->result; + scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, + sshdr); + ret = scmd->result; out: - blk_put_request(req); + blk_mq_free_request(req); return ret; } EXPORT_SYMBOL(__scsi_execute); /* - * Function: scsi_init_cmd_errh() - * - * Purpose: Initialize cmd fields related to error handling. - * - * Arguments: cmd - command that is ready to be queued. - * - * Notes: This function has the job of initializing a number of - * fields related to error handling. Typically this will - * be called once for each command, as required. - */ -static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) -{ - scsi_set_resid(cmd, 0); - memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - if (cmd->cmd_len == 0) - cmd->cmd_len = scsi_command_size(cmd->cmnd); -} - -/* * Wake up the error handler if necessary. Avoid as follows that the error * handler is not woken up if host in-flight requests number == * shost->host_failed: use call_rcu() in scsi_eh_scmd_add() in combination @@ -354,7 +298,8 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd) if (starget->can_queue > 0) atomic_dec(&starget->target_busy); - atomic_dec(&sdev->device_busy); + sbitmap_put(&sdev->budget_map, cmd->budget_token); + cmd->budget_token = -1; } static void scsi_kick_queue(struct request_queue *q) @@ -401,7 +346,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) spin_unlock_irqrestore(shost->host_lock, flags); scsi_kick_queue(sdev->request_queue); spin_lock_irqsave(shost->host_lock, flags); - + scsi_device_put(sdev); } out: @@ -410,7 +355,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) static inline bool scsi_device_is_busy(struct scsi_device *sdev) { - if (atomic_read(&sdev->device_busy) >= sdev->queue_depth) + if (scsi_device_busy(sdev) >= sdev->queue_depth) return true; if (atomic_read(&sdev->device_blocked) > 0) return true; @@ -477,9 +422,9 @@ static void scsi_starved_list_run(struct Scsi_Host *shost) * it and the queue. Mitigate by taking a reference to the * queue and never touching the sdev again after we drop the * host lock. Note: if __scsi_remove_device() invokes - * blk_cleanup_queue() before the queue is run from this + * blk_mq_destroy_queue() before the queue is run from this * function then blk_run_queue() will return immediately since - * blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING. + * blk_mq_destroy_queue() marks the queue with QUEUE_FLAG_DYING. */ slq = sdev->request_queue; if (!blk_get_queue(slq)) @@ -496,17 +441,11 @@ static void scsi_starved_list_run(struct Scsi_Host *shost) spin_unlock_irqrestore(shost->host_lock, flags); } -/* - * Function: scsi_run_queue() - * - * Purpose: Select a proper request queue to serve next - * - * Arguments: q - last request's queue - * - * Returns: Nothing +/** + * scsi_run_queue - Select a proper request queue to serve next. + * @q: last request's queue * - * Notes: The previous command was completely finished, start - * a new one if possible. + * The previous command was completely finished, start a new one if possible. */ static void scsi_run_queue(struct request_queue *q) { @@ -540,7 +479,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) static void scsi_uninit_cmd(struct scsi_cmnd *cmd) { - if (!blk_rq_is_passthrough(cmd->request)) { + if (!blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) { struct scsi_driver *drv = scsi_cmd_to_driver(cmd); if (drv->uninit_command) @@ -548,7 +487,7 @@ static void scsi_uninit_cmd(struct scsi_cmnd *cmd) } } -static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd) +void scsi_free_sgtables(struct scsi_cmnd *cmd) { if (cmd->sdb.table.nents) sg_free_table_chained(&cmd->sdb.table, @@ -557,12 +496,38 @@ static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd) sg_free_table_chained(&cmd->prot_sdb->table, SCSI_INLINE_PROT_SG_CNT); } +EXPORT_SYMBOL_GPL(scsi_free_sgtables); static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd) { - scsi_mq_free_sgtables(cmd); + scsi_free_sgtables(cmd); scsi_uninit_cmd(cmd); - scsi_del_cmd_from_list(cmd); +} + +static void scsi_run_queue_async(struct scsi_device *sdev) +{ + if (scsi_target(sdev)->single_lun || + !list_empty(&sdev->host->starved_list)) { + kblockd_schedule_work(&sdev->requeue_work); + } else { + /* + * smp_mb() present in sbitmap_queue_clear() or implied in + * .end_io is for ordering writing .device_busy in + * scsi_device_unbusy() and reading sdev->restarts. + */ + int old = atomic_read(&sdev->restarts); + + /* + * ->restarts has to be kept as non-zero if new budget + * contention occurs. + * + * No need to run queue when either another re-run + * queue wins in updating ->restarts or a new budget + * contention occurs. + */ + if (old && atomic_cmpxchg(&sdev->restarts, old, 0) == old) + blk_mq_run_hw_queues(sdev->request_queue, true); + } } /* Returns false when no more bytes to process, true if there are more */ @@ -576,10 +541,11 @@ static bool scsi_end_request(struct request *req, blk_status_t error, if (blk_update_request(req, error, bytes)) return true; + // XXX: if (blk_queue_add_random(q)) - add_disk_randomness(req->rq_disk); + add_disk_randomness(req->q->disk); - if (!blk_rq_is_scsi(req)) { + if (!blk_rq_is_passthrough(req)) { WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); cmd->flags &= ~SCMD_INITIALIZED; } @@ -609,72 +575,127 @@ static bool scsi_end_request(struct request *req, blk_status_t error, __blk_mq_end_request(req, error); - if (scsi_target(sdev)->single_lun || - !list_empty(&sdev->host->starved_list)) - kblockd_schedule_work(&sdev->requeue_work); - else - blk_mq_run_hw_queues(q, true); + scsi_run_queue_async(sdev); percpu_ref_put(&q->q_usage_counter); return false; } +static inline u8 get_scsi_ml_byte(int result) +{ + return (result >> 8) & 0xff; +} + /** * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t - * @cmd: SCSI command * @result: scsi error code * - * Translate a SCSI result code into a blk_status_t value. May reset the host - * byte of @cmd->result. + * Translate a SCSI result code into a blk_status_t value. */ -static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result) +static blk_status_t scsi_result_to_blk_status(int result) { + /* + * Check the scsi-ml byte first in case we converted a host or status + * byte. + */ + switch (get_scsi_ml_byte(result)) { + case SCSIML_STAT_OK: + break; + case SCSIML_STAT_RESV_CONFLICT: + return BLK_STS_NEXUS; + case SCSIML_STAT_NOSPC: + return BLK_STS_NOSPC; + case SCSIML_STAT_MED_ERROR: + return BLK_STS_MEDIUM; + case SCSIML_STAT_TGT_FAILURE: + return BLK_STS_TARGET; + } + switch (host_byte(result)) { case DID_OK: - /* - * Also check the other bytes than the status byte in result - * to handle the case when a SCSI LLD sets result to - * DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION. - */ - if (scsi_status_is_good(result) && (result & ~0xff) == 0) + if (scsi_status_is_good(result)) return BLK_STS_OK; return BLK_STS_IOERR; case DID_TRANSPORT_FAILFAST: + case DID_TRANSPORT_MARGINAL: return BLK_STS_TRANSPORT; - case DID_TARGET_FAILURE: - set_host_byte(cmd, DID_OK); - return BLK_STS_TARGET; - case DID_NEXUS_FAILURE: - set_host_byte(cmd, DID_OK); - return BLK_STS_NEXUS; - case DID_ALLOC_FAILURE: - set_host_byte(cmd, DID_OK); - return BLK_STS_NOSPC; - case DID_MEDIUM_ERROR: - set_host_byte(cmd, DID_OK); - return BLK_STS_MEDIUM; default: return BLK_STS_IOERR; } } -/* Helper for scsi_io_completion() when "reprep" action required. */ -static void scsi_io_completion_reprep(struct scsi_cmnd *cmd, - struct request_queue *q) +/** + * scsi_rq_err_bytes - determine number of bytes till the next failure boundary + * @rq: request to examine + * + * Description: + * A request could be merge of IOs which require different failure + * handling. This function determines the number of bytes which + * can be failed from the beginning of the request without + * crossing into area which need to be retried further. + * + * Return: + * The number of bytes to fail. + */ +static unsigned int scsi_rq_err_bytes(const struct request *rq) { - /* A new command will be prepared and issued. */ - scsi_mq_requeue_cmd(cmd); + blk_opf_t ff = rq->cmd_flags & REQ_FAILFAST_MASK; + unsigned int bytes = 0; + struct bio *bio; + + if (!(rq->rq_flags & RQF_MIXED_MERGE)) + return blk_rq_bytes(rq); + + /* + * Currently the only 'mixing' which can happen is between + * different fastfail types. We can safely fail portions + * which have all the failfast bits that the first one has - + * the ones which are at least as eager to fail as the first + * one. + */ + for (bio = rq->bio; bio; bio = bio->bi_next) { + if ((bio->bi_opf & ff) != ff) + break; + bytes += bio->bi_iter.bi_size; + } + + /* this could lead to infinite loop */ + BUG_ON(blk_rq_bytes(rq) && !bytes); + return bytes; } +static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) +{ + struct request *req = scsi_cmd_to_rq(cmd); + unsigned long wait_for; + + if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) + return false; + + wait_for = (cmd->allowed + 1) * req->timeout; + if (time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { + scmd_printk(KERN_ERR, cmd, "timing out command, waited %lus\n", + wait_for/HZ); + return true; + } + return false; +} + +/* + * When ALUA transition state is returned, reprep the cmd to + * use the ALUA handler's transition timeout. Delay the reprep + * 1 sec to avoid aggressive retries of the target in that + * state. + */ +#define ALUA_TRANSITION_REPREP_DELAY 1000 + /* Helper for scsi_io_completion() when special action required. */ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) { - struct request_queue *q = cmd->device->request_queue; - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); int level = 0; - enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY, - ACTION_DELAYED_RETRY} action; - unsigned long wait_for = (cmd->allowed + 1) * req->timeout; + enum {ACTION_FAIL, ACTION_REPREP, ACTION_DELAYED_REPREP, + ACTION_RETRY, ACTION_DELAYED_RETRY} action; struct scsi_sense_hdr sshdr; bool sense_valid; bool sense_current = true; /* false implies "deferred sense" */ @@ -684,7 +705,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) if (sense_valid) sense_current = !scsi_sense_is_deferred(&sshdr); - blk_stat = scsi_result_to_blk_status(cmd, result); + blk_stat = scsi_result_to_blk_status(result); if (host_byte(result) == DID_RESET) { /* Third party bus reset or reset for error recovery @@ -754,6 +775,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x11: /* notify (enable spinup) required */ case 0x14: /* space allocation in progress */ case 0x1a: /* start stop unit in progress */ case 0x1b: /* sanitize in progress */ @@ -761,6 +783,9 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) case 0x24: /* depopulation in progress */ action = ACTION_DELAYED_RETRY; break; + case 0x0a: /* ALUA state transition */ + action = ACTION_DELAYED_REPREP; + break; default: action = ACTION_FAIL; break; @@ -772,6 +797,15 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) /* See SSC3rXX or current. */ action = ACTION_FAIL; break; + case DATA_PROTECT: + action = ACTION_FAIL; + if ((sshdr.asc == 0x0C && sshdr.ascq == 0x12) || + (sshdr.asc == 0x55 && + (sshdr.ascq == 0x0E || sshdr.ascq == 0x0F))) { + /* Insufficient zone resources */ + blk_stat = BLK_STS_ZONE_OPEN_RESOURCE; + } + break; default: action = ACTION_FAIL; break; @@ -779,8 +813,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) } else action = ACTION_FAIL; - if (action != ACTION_FAIL && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) + if (action != ACTION_FAIL && scsi_cmd_runtime_exceeced(cmd)) action = ACTION_FAIL; switch (action) { @@ -802,16 +835,19 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) */ if (!level && __ratelimit(&_rs)) { scsi_print_result(cmd, NULL, FAILED); - if (driver_byte(result) == DRIVER_SENSE) + if (sense_valid) scsi_print_sense(cmd); scsi_print_command(cmd); } } - if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req))) + if (!scsi_end_request(req, blk_stat, scsi_rq_err_bytes(req))) return; - /*FALLTHRU*/ + fallthrough; case ACTION_REPREP: - scsi_io_completion_reprep(cmd, q); + scsi_mq_requeue_cmd(cmd, 0); + break; + case ACTION_DELAYED_REPREP: + scsi_mq_requeue_cmd(cmd, ALUA_TRANSITION_REPREP_DELAY); break; case ACTION_RETRY: /* Retry the same command immediately */ @@ -834,7 +870,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, { bool sense_valid; bool sense_current = true; /* false implies "deferred sense" */ - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); struct scsi_sense_hdr sshdr; sense_valid = scsi_command_normalize_sense(cmd, &sshdr); @@ -846,19 +882,18 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, /* * SG_IO wants current and deferred errors */ - scsi_req(req)->sense_len = - min(8 + cmd->sense_buffer[7], - SCSI_SENSE_BUFFERSIZE); + cmd->sense_len = min(8 + cmd->sense_buffer[7], + SCSI_SENSE_BUFFERSIZE); } if (sense_current) - *blk_statp = scsi_result_to_blk_status(cmd, result); + *blk_statp = scsi_result_to_blk_status(result); } else if (blk_rq_bytes(req) == 0 && sense_current) { /* * Flush commands do not transfers any data, and thus cannot use * good_bytes != blk_rq_bytes(req) as the signal for an error. * This sets *blk_statp explicitly for the problem case. */ - *blk_statp = scsi_result_to_blk_status(cmd, result); + *blk_statp = scsi_result_to_blk_status(result); } /* * Recovered errors need reporting, but they're always treated as @@ -890,59 +925,44 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related * intermediate statuses (both obsolete in SAM-4) as good. */ - if (status_byte(result) && scsi_status_is_good(result)) { + if ((result & 0xff) && scsi_status_is_good(result)) { result = 0; *blk_statp = BLK_STS_OK; } return result; } -/* - * Function: scsi_io_completion() - * - * Purpose: Completion processing for block device I/O requests. - * - * Arguments: cmd - command that is finished. - * - * Lock status: Assumed that no lock is held upon entry. - * - * Returns: Nothing - * - * Notes: We will finish off the specified number of sectors. If we - * are done, the command block will be released and the queue - * function will be goosed. If we are not done then we have to - * figure out what to do next: - * - * a) We can call scsi_requeue_command(). The request - * will be unprepared and put back on the queue. Then - * a new command will be created for it. This should - * be used if we made forward progress, or if we want - * to switch from READ(10) to READ(6) for example. - * - * b) We can call __scsi_queue_insert(). The request will - * be put back on the queue and retried using the same - * command as before, possibly after a delay. - * - * c) We can call scsi_end_request() with blk_stat other than - * BLK_STS_OK, to fail the remainder of the request. +/** + * scsi_io_completion - Completion processing for SCSI commands. + * @cmd: command that is finished. + * @good_bytes: number of processed bytes. + * + * We will finish off the specified number of sectors. If we are done, the + * command block will be released and the queue function will be goosed. If we + * are not done then we have to figure out what to do next: + * + * a) We can call scsi_mq_requeue_cmd(). The request will be + * unprepared and put back on the queue. Then a new command will + * be created for it. This should be used if we made forward + * progress, or if we want to switch from READ(10) to READ(6) for + * example. + * + * b) We can call scsi_io_completion_action(). The request will be + * put back on the queue and retried using the same command as + * before, possibly after a delay. + * + * c) We can call scsi_end_request() with blk_stat other than + * BLK_STS_OK, to fail the remainder of the request. */ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - struct request_queue *q = cmd->device->request_queue; - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); blk_status_t blk_stat = BLK_STS_OK; if (unlikely(result)) /* a nz result may or may not be an error */ result = scsi_io_completion_nz_result(cmd, result, &blk_stat); - if (unlikely(blk_rq_is_passthrough(req))) { - /* - * scsi_result_to_blk_status may have reset the host_byte - */ - scsi_req(req)->result = cmd->result; - } - /* * Next deal with any sectors which we were able to correctly * handle. @@ -952,8 +972,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) blk_rq_sectors(req), good_bytes)); /* - * Next deal with any sectors which we were able to correctly - * handle. Failed, zero length commands always need to drop down + * Failed, zero length commands always need to drop down * to retry code. Fast path should return in this block. */ if (likely(blk_rq_bytes(req) > 0 || blk_stat == BLK_STS_OK)) { @@ -971,64 +990,92 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) /* * If there had been no error, but we have leftover bytes in the - * requeues just queue the command up again. + * request just queue the command up again. */ if (likely(result == 0)) - scsi_io_completion_reprep(cmd, q); + scsi_mq_requeue_cmd(cmd, 0); else scsi_io_completion_action(cmd, result); } -static blk_status_t scsi_init_sgtable(struct request *req, - struct scsi_data_buffer *sdb) +static inline bool scsi_cmd_needs_dma_drain(struct scsi_device *sdev, + struct request *rq) +{ + return sdev->dma_drain_len && blk_rq_is_passthrough(rq) && + !op_is_write(req_op(rq)) && + sdev->host->hostt->dma_need_drain(rq); +} + +/** + * scsi_alloc_sgtables - Allocate and initialize data and integrity scatterlists + * @cmd: SCSI command data structure to initialize. + * + * Initializes @cmd->sdb and also @cmd->prot_sdb if data integrity is enabled + * for @cmd. + * + * Returns: + * * BLK_STS_OK - on success + * * BLK_STS_RESOURCE - if the failure is retryable + * * BLK_STS_IOERR - if the failure is fatal + */ +blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd) { + struct scsi_device *sdev = cmd->device; + struct request *rq = scsi_cmd_to_rq(cmd); + unsigned short nr_segs = blk_rq_nr_phys_segments(rq); + struct scatterlist *last_sg = NULL; + blk_status_t ret; + bool need_drain = scsi_cmd_needs_dma_drain(sdev, rq); int count; + if (WARN_ON_ONCE(!nr_segs)) + return BLK_STS_IOERR; + + /* + * Make sure there is space for the drain. The driver must adjust + * max_hw_segments to be prepared for this. + */ + if (need_drain) + nr_segs++; + /* * If sg table allocation fails, requeue request later. */ - if (unlikely(sg_alloc_table_chained(&sdb->table, - blk_rq_nr_phys_segments(req), sdb->table.sgl, - SCSI_INLINE_SG_CNT))) + if (unlikely(sg_alloc_table_chained(&cmd->sdb.table, nr_segs, + cmd->sdb.table.sgl, SCSI_INLINE_SG_CNT))) return BLK_STS_RESOURCE; - /* + /* * Next, walk the list, and fill in the addresses and sizes of * each segment. */ - count = blk_rq_map_sg(req->q, req, sdb->table.sgl); - BUG_ON(count > sdb->table.nents); - sdb->table.nents = count; - sdb->length = blk_rq_payload_bytes(req); - return BLK_STS_OK; -} + count = __blk_rq_map_sg(rq->q, rq, cmd->sdb.table.sgl, &last_sg); -/* - * Function: scsi_init_io() - * - * Purpose: SCSI I/O initialize function. - * - * Arguments: cmd - Command descriptor we wish to initialize - * - * Returns: BLK_STS_OK on success - * BLK_STS_RESOURCE if the failure is retryable - * BLK_STS_IOERR if the failure is fatal - */ -blk_status_t scsi_init_io(struct scsi_cmnd *cmd) -{ - struct request *rq = cmd->request; - blk_status_t ret; + if (blk_rq_bytes(rq) & rq->q->dma_pad_mask) { + unsigned int pad_len = + (rq->q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1; - if (WARN_ON_ONCE(!blk_rq_nr_phys_segments(rq))) - return BLK_STS_IOERR; + last_sg->length += pad_len; + cmd->extra_len += pad_len; + } + + if (need_drain) { + sg_unmark_end(last_sg); + last_sg = sg_next(last_sg); + sg_set_buf(last_sg, sdev->dma_drain_buf, sdev->dma_drain_len); + sg_mark_end(last_sg); + + cmd->extra_len += sdev->dma_drain_len; + count++; + } - ret = scsi_init_sgtable(rq, &cmd->sdb); - if (ret) - return ret; + BUG_ON(count > cmd->sdb.table.nents); + cmd->sdb.table.nents = count; + cmd->sdb.length = blk_rq_payload_bytes(rq); if (blk_integrity_rq(rq)) { struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; - int ivecs, count; + int ivecs; if (WARN_ON_ONCE(!prot_sdb)) { /* @@ -1060,10 +1107,10 @@ blk_status_t scsi_init_io(struct scsi_cmnd *cmd) return BLK_STS_OK; out_free_sgtables: - scsi_mq_free_sgtables(cmd); + scsi_free_sgtables(cmd); return ret; } -EXPORT_SYMBOL(scsi_init_io); +EXPORT_SYMBOL(scsi_alloc_sgtables); /** * scsi_initialize_rq - initialize struct scsi_cmnd partially @@ -1072,20 +1119,31 @@ EXPORT_SYMBOL(scsi_init_io); * This function initializes the members of struct scsi_cmnd that must be * initialized before request processing starts and that won't be * reinitialized if a SCSI command is requeued. - * - * Called from inside blk_get_request() for pass-through requests and from - * inside scsi_init_command() for filesystem requests. */ static void scsi_initialize_rq(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); - scsi_req_init(&cmd->req); + memset(cmd->cmnd, 0, sizeof(cmd->cmnd)); + cmd->cmd_len = MAX_COMMAND_SIZE; + cmd->sense_len = 0; init_rcu_head(&cmd->rcu); cmd->jiffies_at_alloc = jiffies; cmd->retries = 0; } +struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf, + blk_mq_req_flags_t flags) +{ + struct request *rq; + + rq = blk_mq_alloc_request(q, opf, flags); + if (!IS_ERR(rq)) + scsi_initialize_rq(rq); + return rq; +} +EXPORT_SYMBOL_GPL(scsi_alloc_request); + /* * Only called when the request isn't completed by SCSI, and not freed by * SCSI @@ -1098,69 +1156,19 @@ static void scsi_cleanup_rq(struct request *rq) } } -/* Add a command to the list used by the aacraid and dpt_i2o drivers */ -void scsi_add_cmd_to_list(struct scsi_cmnd *cmd) -{ - struct scsi_device *sdev = cmd->device; - struct Scsi_Host *shost = sdev->host; - unsigned long flags; - - if (shost->use_cmd_list) { - spin_lock_irqsave(&sdev->list_lock, flags); - list_add_tail(&cmd->list, &sdev->cmd_list); - spin_unlock_irqrestore(&sdev->list_lock, flags); - } -} - -/* Remove a command from the list used by the aacraid and dpt_i2o drivers */ -void scsi_del_cmd_from_list(struct scsi_cmnd *cmd) -{ - struct scsi_device *sdev = cmd->device; - struct Scsi_Host *shost = sdev->host; - unsigned long flags; - - if (shost->use_cmd_list) { - spin_lock_irqsave(&sdev->list_lock, flags); - BUG_ON(list_empty(&cmd->list)); - list_del_init(&cmd->list); - spin_unlock_irqrestore(&sdev->list_lock, flags); - } -} - -/* Called after a request has been started. */ +/* Called before a request is prepared. See also scsi_mq_prep_fn(). */ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) { - void *buf = cmd->sense_buffer; - void *prot = cmd->prot_sdb; - struct request *rq = blk_mq_rq_from_pdu(cmd); - unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; - unsigned long jiffies_at_alloc; - int retries; - bool in_flight; + struct request *rq = scsi_cmd_to_rq(cmd); - if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) { - flags |= SCMD_INITIALIZED; + if (!blk_rq_is_passthrough(rq) && !(cmd->flags & SCMD_INITIALIZED)) { + cmd->flags |= SCMD_INITIALIZED; scsi_initialize_rq(rq); } - jiffies_at_alloc = cmd->jiffies_at_alloc; - retries = cmd->retries; - in_flight = test_bit(SCMD_STATE_INFLIGHT, &cmd->state); - /* zero out the cmd, except for the embedded scsi_request */ - memset((char *)cmd + sizeof(cmd->req), 0, - sizeof(*cmd) - sizeof(cmd->req) + dev->host->hostt->cmd_size); - cmd->device = dev; - cmd->sense_buffer = buf; - cmd->prot_sdb = prot; - cmd->flags = flags; + INIT_LIST_HEAD(&cmd->eh_entry); INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); - cmd->jiffies_at_alloc = jiffies_at_alloc; - cmd->retries = retries; - if (in_flight) - __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); - - scsi_add_cmd_to_list(cmd); } static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev, @@ -1175,7 +1183,7 @@ static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev, * submit a request without an attached bio. */ if (req->bio) { - blk_status_t ret = scsi_init_io(cmd); + blk_status_t ret = scsi_alloc_sgtables(cmd); if (unlikely(ret != BLK_STS_OK)) return ret; } else { @@ -1184,55 +1192,16 @@ static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev, memset(&cmd->sdb, 0, sizeof(cmd->sdb)); } - cmd->cmd_len = scsi_req(req)->cmd_len; - cmd->cmnd = scsi_req(req)->cmd; cmd->transfersize = blk_rq_bytes(req); - cmd->allowed = scsi_req(req)->retries; return BLK_STS_OK; } -/* - * Setup a normal block command. These are simple request from filesystems - * that still need to be translated to SCSI CDBs from the ULD. - */ -static blk_status_t scsi_setup_fs_cmnd(struct scsi_device *sdev, - struct request *req) -{ - struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); - - if (unlikely(sdev->handler && sdev->handler->prep_fn)) { - blk_status_t ret = sdev->handler->prep_fn(sdev, req); - if (ret != BLK_STS_OK) - return ret; - } - - cmd->cmnd = scsi_req(req)->cmd = scsi_req(req)->__cmd; - memset(cmd->cmnd, 0, BLK_MAX_CDB); - return scsi_cmd_to_driver(cmd)->init_command(cmd); -} - -static blk_status_t scsi_setup_cmnd(struct scsi_device *sdev, - struct request *req) -{ - struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); - - if (!blk_rq_bytes(req)) - cmd->sc_data_direction = DMA_NONE; - else if (rq_data_dir(req) == WRITE) - cmd->sc_data_direction = DMA_TO_DEVICE; - else - cmd->sc_data_direction = DMA_FROM_DEVICE; - - if (blk_rq_is_scsi(req)) - return scsi_setup_scsi_cmnd(sdev, req); - else - return scsi_setup_fs_cmnd(sdev, req); -} - static blk_status_t -scsi_prep_state_check(struct scsi_device *sdev, struct request *req) +scsi_device_state_check(struct scsi_device *sdev, struct request *req) { switch (sdev->sdev_state) { + case SDEV_CREATED: + return BLK_STS_OK; case SDEV_OFFLINE: case SDEV_TRANSPORT_OFFLINE: /* @@ -1240,8 +1209,11 @@ scsi_prep_state_check(struct scsi_device *sdev, struct request *req) * commands. The device must be brought online * before trying any recovery commands. */ - sdev_printk(KERN_ERR, sdev, - "rejecting I/O to offline device\n"); + if (!sdev->offline_already) { + sdev->offline_already = true; + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to offline device\n"); + } return BLK_STS_IOERR; case SDEV_DEL: /* @@ -1256,37 +1228,38 @@ scsi_prep_state_check(struct scsi_device *sdev, struct request *req) return BLK_STS_RESOURCE; case SDEV_QUIESCE: /* - * If the devices is blocked we defer normal commands. + * If the device is blocked we only accept power management + * commands. */ - if (req && !(req->rq_flags & RQF_PREEMPT)) + if (req && WARN_ON_ONCE(!(req->rq_flags & RQF_PM))) return BLK_STS_RESOURCE; return BLK_STS_OK; default: /* * For any other not fully online state we only allow - * special commands. In particular any user initiated - * command is not allowed. + * power management commands. */ - if (req && !(req->rq_flags & RQF_PREEMPT)) - return BLK_STS_IOERR; + if (req && !(req->rq_flags & RQF_PM)) + return BLK_STS_OFFLINE; return BLK_STS_OK; } } /* - * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else - * return 0. - * - * Called with the queue_lock held. + * scsi_dev_queue_ready: if we can send requests to sdev, assign one token + * and return the token else return -1. */ static inline int scsi_dev_queue_ready(struct request_queue *q, struct scsi_device *sdev) { - unsigned int busy; + int token; - busy = atomic_inc_return(&sdev->device_busy) - 1; + token = sbitmap_get(&sdev->budget_map); if (atomic_read(&sdev->device_blocked)) { - if (busy) + if (token < 0) + goto out; + + if (scsi_device_busy(sdev) > 1) goto out_dec; /* @@ -1298,13 +1271,12 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, "unblocking device at zero depth\n")); } - if (busy >= sdev->queue_depth) - goto out_dec; - - return 1; + return token; out_dec: - atomic_dec(&sdev->device_busy); - return 0; + if (token >= 0) + sbitmap_put(&sdev->budget_map, token); +out: + return -1; } /* @@ -1448,11 +1420,14 @@ static bool scsi_mq_lld_busy(struct request_queue *q) return false; } -static void scsi_softirq_done(struct request *rq) +/* + * Block layer request completion callback. May be called from interrupt + * context. + */ +static void scsi_complete(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); - unsigned long wait_for = (cmd->allowed + 1) * rq->timeout; - int disposition; + enum scsi_disposition disposition; INIT_LIST_HEAD(&cmd->eh_entry); @@ -1461,34 +1436,29 @@ static void scsi_softirq_done(struct request *rq) atomic_inc(&cmd->device->ioerr_cnt); disposition = scsi_decide_disposition(cmd); - if (disposition != SUCCESS && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { - scmd_printk(KERN_ERR, cmd, - "timing out command, waited %lus\n", - wait_for/HZ); + if (disposition != SUCCESS && scsi_cmd_runtime_exceeced(cmd)) disposition = SUCCESS; - } scsi_log_completion(cmd, disposition); switch (disposition) { - case SUCCESS: - scsi_finish_command(cmd); - break; - case NEEDS_RETRY: - scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); - break; - case ADD_TO_MLQUEUE: - scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); - break; - default: - scsi_eh_scmd_add(cmd); - break; + case SUCCESS: + scsi_finish_command(cmd); + break; + case NEEDS_RETRY: + scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); + break; + case ADD_TO_MLQUEUE: + scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); + break; + default: + scsi_eh_scmd_add(cmd); + break; } } /** - * scsi_dispatch_command - Dispatch a command to the low-level driver. + * scsi_dispatch_cmd - Dispatch a command to the low-level driver. * @cmd: command block we are dispatching. * * Return: nonzero return request was rejected and device's queue needs to be @@ -1564,7 +1534,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) return rtn; done: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } @@ -1575,18 +1545,42 @@ static unsigned int scsi_mq_inline_sgl_size(struct Scsi_Host *shost) sizeof(struct scatterlist); } -static blk_status_t scsi_mq_prep_fn(struct request *req) +static blk_status_t scsi_prepare_cmd(struct request *req) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); struct scsi_device *sdev = req->q->queuedata; struct Scsi_Host *shost = sdev->host; + bool in_flight = test_bit(SCMD_STATE_INFLIGHT, &cmd->state); struct scatterlist *sg; scsi_init_command(sdev, cmd); - cmd->request = req; - cmd->tag = req->tag; + cmd->eh_eflags = 0; + cmd->prot_type = 0; + cmd->prot_flags = 0; + cmd->submitter = 0; + memset(&cmd->sdb, 0, sizeof(cmd->sdb)); + cmd->underflow = 0; + cmd->transfersize = 0; + cmd->host_scribble = NULL; + cmd->result = 0; + cmd->extra_len = 0; + cmd->state = 0; + if (in_flight) + __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); + + /* + * Only clear the driver-private command data if the LLD does not supply + * a function to initialize that data. + */ + if (!shost->hostt->init_cmd_priv) + memset(cmd + 1, 0, shost->hostt->cmd_size); + cmd->prot_op = SCSI_PROT_NORMAL; + if (blk_rq_bytes(req)) + cmd->sc_data_direction = rq_dma_dir(req); + else + cmd->sc_data_direction = DMA_NONE; sg = (void *)cmd + sizeof(struct scsi_cmnd) + shost->hostt->cmd_size; cmd->sdb.table.sgl = sg; @@ -1598,46 +1592,120 @@ static blk_status_t scsi_mq_prep_fn(struct request *req) (struct scatterlist *)(cmd->prot_sdb + 1); } - blk_mq_start_request(req); + /* + * Special handling for passthrough commands, which don't go to the ULP + * at all: + */ + if (blk_rq_is_passthrough(req)) + return scsi_setup_scsi_cmnd(sdev, req); + + if (sdev->handler && sdev->handler->prep_fn) { + blk_status_t ret = sdev->handler->prep_fn(sdev, req); + + if (ret != BLK_STS_OK) + return ret; + } - return scsi_setup_cmnd(sdev, req); + /* Usually overridden by the ULP */ + cmd->allowed = 0; + memset(cmd->cmnd, 0, sizeof(cmd->cmnd)); + return scsi_cmd_to_driver(cmd)->init_command(cmd); } -static void scsi_mq_done(struct scsi_cmnd *cmd) +static void scsi_done_internal(struct scsi_cmnd *cmd, bool complete_directly) { + struct request *req = scsi_cmd_to_rq(cmd); + + switch (cmd->submitter) { + case SUBMITTED_BY_BLOCK_LAYER: + break; + case SUBMITTED_BY_SCSI_ERROR_HANDLER: + return scsi_eh_done(cmd); + case SUBMITTED_BY_SCSI_RESET_IOCTL: + return; + } + + if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q))) + return; if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) return; trace_scsi_dispatch_cmd_done(cmd); - /* - * If the block layer didn't complete the request due to a timeout - * injection, scsi must clear its internal completed state so that the - * timeout handler will see it needs to escalate its own error - * recovery. - */ - if (unlikely(!blk_mq_complete_request(cmd->request))) - clear_bit(SCMD_STATE_COMPLETE, &cmd->state); + if (complete_directly) + blk_mq_complete_request_direct(req, scsi_complete); + else + blk_mq_complete_request(req); +} + +void scsi_done(struct scsi_cmnd *cmd) +{ + scsi_done_internal(cmd, false); } +EXPORT_SYMBOL(scsi_done); -static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) +void scsi_done_direct(struct scsi_cmnd *cmd) +{ + scsi_done_internal(cmd, true); +} +EXPORT_SYMBOL(scsi_done_direct); + +static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { - struct request_queue *q = hctx->queue; struct scsi_device *sdev = q->queuedata; - atomic_dec(&sdev->device_busy); + sbitmap_put(&sdev->budget_map, budget_token); } -static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) +/* + * When to reinvoke queueing after a resource shortage. It's 3 msecs to + * not change behaviour from the previous unplug mechanism, experimentation + * may prove this needs changing. + */ +#define SCSI_QUEUE_DELAY 3 + +static int scsi_mq_get_budget(struct request_queue *q) { - struct request_queue *q = hctx->queue; struct scsi_device *sdev = q->queuedata; + int token = scsi_dev_queue_ready(q, sdev); - if (scsi_dev_queue_ready(q, sdev)) - return true; + if (token >= 0) + return token; - if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) - blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); - return false; + atomic_inc(&sdev->restarts); + + /* + * Orders atomic_inc(&sdev->restarts) and atomic_read(&sdev->device_busy). + * .restarts must be incremented before .device_busy is read because the + * code in scsi_run_queue_async() depends on the order of these operations. + */ + smp_mb__after_atomic(); + + /* + * If all in-flight requests originated from this LUN are completed + * before reading .device_busy, sdev->device_busy will be observed as + * zero, then blk_mq_delay_run_hw_queues() will dispatch this request + * soon. Otherwise, completion of one of these requests will observe + * the .restarts flag, and the request queue will be run for handling + * this request, see scsi_end_request(). + */ + if (unlikely(scsi_device_busy(sdev) == 0 && + !scsi_device_blocked(sdev))) + blk_mq_delay_run_hw_queues(sdev->request_queue, SCSI_QUEUE_DELAY); + return -1; +} + +static void scsi_mq_set_rq_budget_token(struct request *req, int token) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + + cmd->budget_token = token; +} + +static int scsi_mq_get_rq_budget_token(struct request *req) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + + return cmd->budget_token; } static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, @@ -1651,12 +1719,14 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, blk_status_t ret; int reason; + WARN_ON_ONCE(cmd->budget_token < 0); + /* * If the device is not in running state we will reject some or all * commands. */ if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { - ret = scsi_prep_state_check(sdev, req); + ret = scsi_device_state_check(sdev, req); if (ret != BLK_STS_OK) goto out_put_budget; } @@ -1668,13 +1738,12 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, goto out_dec_target_busy; if (!(req->rq_flags & RQF_DONTPREP)) { - ret = scsi_mq_prep_fn(req); + ret = scsi_prepare_cmd(req); if (ret != BLK_STS_OK) goto out_dec_host_busy; req->rq_flags |= RQF_DONTPREP; } else { clear_bit(SCMD_STATE_COMPLETE, &cmd->state); - blk_mq_start_request(req); } cmd->flags &= SCMD_PRESERVED_FLAGS; @@ -1683,9 +1752,11 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, if (bd->last) cmd->flags |= SCMD_LAST; - scsi_init_cmd_errh(cmd); - cmd->scsi_done = scsi_mq_done; + scsi_set_resid(cmd, 0); + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + cmd->submitter = SUBMITTED_BY_BLOCK_LAYER; + blk_mq_start_request(req); reason = scsi_dispatch_cmd(cmd); if (reason) { scsi_set_blocked(cmd, reason); @@ -1701,20 +1772,26 @@ out_dec_target_busy: if (scsi_target(sdev)->can_queue > 0) atomic_dec(&scsi_target(sdev)->target_busy); out_put_budget: - scsi_mq_put_budget(hctx); + scsi_mq_put_budget(q, cmd->budget_token); + cmd->budget_token = -1; switch (ret) { case BLK_STS_OK: break; case BLK_STS_RESOURCE: - if (atomic_read(&sdev->device_busy) || - scsi_device_blocked(sdev)) + case BLK_STS_ZONE_RESOURCE: + if (scsi_device_blocked(sdev)) ret = BLK_STS_DEV_RESOURCE; break; + case BLK_STS_AGAIN: + cmd->result = DID_BUS_BUSY << 16; + if (req->rq_flags & RQF_DONTPREP) + scsi_mq_uninit_cmd(cmd); + break; default: if (unlikely(!scsi_device_online(sdev))) - scsi_req(req)->result = DID_NO_CONNECT << 16; + cmd->result = DID_NO_CONNECT << 16; else - scsi_req(req)->result = DID_ERROR << 16; + cmd->result = DID_ERROR << 16; /* * Make sure to release all allocated resources when * we hit an error, as we will never see this command @@ -1722,34 +1799,24 @@ out_put_budget: */ if (req->rq_flags & RQF_DONTPREP) scsi_mq_uninit_cmd(cmd); + scsi_run_queue_async(sdev); break; } return ret; } -static enum blk_eh_timer_return scsi_timeout(struct request *req, - bool reserved) -{ - if (reserved) - return BLK_EH_RESET_TIMER; - return scsi_times_out(req); -} - static int scsi_mq_init_request(struct blk_mq_tag_set *set, struct request *rq, unsigned int hctx_idx, unsigned int numa_node) { struct Scsi_Host *shost = set->driver_data; - const bool unchecked_isa_dma = shost->unchecked_isa_dma; struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); struct scatterlist *sg; + int ret = 0; - if (unchecked_isa_dma) - cmd->flags |= SCMD_UNCHECKED_ISA_DMA; - cmd->sense_buffer = scsi_alloc_sense_buffer(unchecked_isa_dma, - GFP_KERNEL, numa_node); + cmd->sense_buffer = + kmem_cache_alloc_node(scsi_sense_cache, GFP_KERNEL, numa_node); if (!cmd->sense_buffer) return -ENOMEM; - cmd->req.sense = cmd->sense_buffer; if (scsi_host_get_prot(shost)) { sg = (void *)cmd + sizeof(struct scsi_cmnd) + @@ -1757,25 +1824,53 @@ static int scsi_mq_init_request(struct blk_mq_tag_set *set, struct request *rq, cmd->prot_sdb = (void *)sg + scsi_mq_inline_sgl_size(shost); } - return 0; + if (shost->hostt->init_cmd_priv) { + ret = shost->hostt->init_cmd_priv(shost, cmd); + if (ret < 0) + kmem_cache_free(scsi_sense_cache, cmd->sense_buffer); + } + + return ret; } static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq, unsigned int hctx_idx) { + struct Scsi_Host *shost = set->driver_data; struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); - scsi_free_sense_buffer(cmd->flags & SCMD_UNCHECKED_ISA_DMA, - cmd->sense_buffer); + if (shost->hostt->exit_cmd_priv) + shost->hostt->exit_cmd_priv(shost, cmd); + kmem_cache_free(scsi_sense_cache, cmd->sense_buffer); +} + + +static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) +{ + struct Scsi_Host *shost = hctx->driver_data; + + if (shost->hostt->mq_poll) + return shost->hostt->mq_poll(shost, hctx->queue_num); + + return 0; +} + +static int scsi_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int hctx_idx) +{ + struct Scsi_Host *shost = data; + + hctx->driver_data = shost; + return 0; } -static int scsi_map_queues(struct blk_mq_tag_set *set) +static void scsi_map_queues(struct blk_mq_tag_set *set) { struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set); if (shost->hostt->map_queues) return shost->hostt->map_queues(shost); - return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); + blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); } void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) @@ -1796,13 +1891,7 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) blk_queue_max_integrity_segments(q, shost->sg_prot_tablesize); } - if (dev->dma_mask) { - shost->max_sectors = min_t(unsigned int, shost->max_sectors, - dma_max_mapping_size(dev) >> SECTOR_SHIFT); - } blk_queue_max_hw_sectors(q, shost->max_sectors); - if (shost->unchecked_isa_dma) - blk_queue_bounce_limit(q, BLK_BOUNCE_ISA); blk_queue_segment_boundary(q, shost->dma_boundary); dma_set_seg_boundary(dev, shost->dma_boundary); @@ -1825,25 +1914,26 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .get_budget = scsi_mq_get_budget, .put_budget = scsi_mq_put_budget, .queue_rq = scsi_queue_rq, - .complete = scsi_softirq_done, + .complete = scsi_complete, .timeout = scsi_timeout, #ifdef CONFIG_BLK_DEBUG_FS .show_rq = scsi_show_rq, #endif .init_request = scsi_mq_init_request, .exit_request = scsi_mq_exit_request, - .initialize_rq_fn = scsi_initialize_rq, .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .init_hctx = scsi_init_hctx, + .poll = scsi_mq_poll, + .set_rq_budget_token = scsi_mq_set_rq_budget_token, + .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; static void scsi_commit_rqs(struct blk_mq_hw_ctx *hctx) { - struct request_queue *q = hctx->queue; - struct scsi_device *sdev = q->queuedata; - struct Scsi_Host *shost = sdev->host; + struct Scsi_Host *shost = hctx->driver_data; shost->hostt->commit_rqs(shost, hctx->queue_num); } @@ -1853,34 +1943,26 @@ static const struct blk_mq_ops scsi_mq_ops = { .put_budget = scsi_mq_put_budget, .queue_rq = scsi_queue_rq, .commit_rqs = scsi_commit_rqs, - .complete = scsi_softirq_done, + .complete = scsi_complete, .timeout = scsi_timeout, #ifdef CONFIG_BLK_DEBUG_FS .show_rq = scsi_show_rq, #endif .init_request = scsi_mq_init_request, .exit_request = scsi_mq_exit_request, - .initialize_rq_fn = scsi_initialize_rq, .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .init_hctx = scsi_init_hctx, + .poll = scsi_mq_poll, + .set_rq_budget_token = scsi_mq_set_rq_budget_token, + .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; -struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev) -{ - sdev->request_queue = blk_mq_init_queue(&sdev->host->tag_set); - if (IS_ERR(sdev->request_queue)) - return NULL; - - sdev->request_queue->queuedata = sdev; - __scsi_init_queue(sdev->host, sdev->request_queue); - blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, sdev->request_queue); - return sdev->request_queue; -} - int scsi_mq_setup_tags(struct Scsi_Host *shost) { unsigned int cmd_size, sgl_size; + struct blk_mq_tag_set *tag_set = &shost->tag_set; sgl_size = max_t(unsigned int, sizeof(struct scatterlist), scsi_mq_inline_sgl_size(shost)); @@ -1889,26 +1971,33 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) cmd_size += sizeof(struct scsi_data_buffer) + sizeof(struct scatterlist) * SCSI_INLINE_PROT_SG_CNT; - memset(&shost->tag_set, 0, sizeof(shost->tag_set)); + memset(tag_set, 0, sizeof(*tag_set)); if (shost->hostt->commit_rqs) - shost->tag_set.ops = &scsi_mq_ops; + tag_set->ops = &scsi_mq_ops; else - shost->tag_set.ops = &scsi_mq_ops_no_commit; - shost->tag_set.nr_hw_queues = shost->nr_hw_queues ? : 1; - shost->tag_set.queue_depth = shost->can_queue; - shost->tag_set.cmd_size = cmd_size; - shost->tag_set.numa_node = NUMA_NO_NODE; - shost->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; - shost->tag_set.flags |= + tag_set->ops = &scsi_mq_ops_no_commit; + tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1; + tag_set->nr_maps = shost->nr_maps ? : 1; + tag_set->queue_depth = shost->can_queue; + tag_set->cmd_size = cmd_size; + tag_set->numa_node = dev_to_node(shost->dma_dev); + tag_set->flags = BLK_MQ_F_SHOULD_MERGE; + tag_set->flags |= BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy); - shost->tag_set.driver_data = shost; + tag_set->driver_data = shost; + if (shost->host_tagset) + tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; - return blk_mq_alloc_tag_set(&shost->tag_set); + return blk_mq_alloc_tag_set(tag_set); } -void scsi_mq_destroy_tags(struct Scsi_Host *shost) +void scsi_mq_free_tags(struct kref *kref) { + struct Scsi_Host *shost = container_of(kref, typeof(*shost), + tagset_refcnt); + blk_mq_free_tag_set(&shost->tag_set); + complete(&shost->tagset_freed); } /** @@ -1930,23 +2019,22 @@ struct scsi_device *scsi_device_from_queue(struct request_queue *q) return sdev; } +/* + * pktcdvd should have been integrated into the SCSI layers, but for historical + * reasons like the old IDE driver it isn't. This export allows it to safely + * probe if a given device is a SCSI one and only attach to that. + */ +#ifdef CONFIG_CDROM_PKTCDVD_MODULE EXPORT_SYMBOL_GPL(scsi_device_from_queue); +#endif -/* - * Function: scsi_block_requests() - * - * Purpose: Utility function used by low-level drivers to prevent further - * commands from being queued to the device. - * - * Arguments: shost - Host in question - * - * Returns: Nothing - * - * Lock status: No locks are assumed held. +/** + * scsi_block_requests - Utility function used by low-level drivers to prevent + * further commands from being queued to the device. + * @shost: host in question * - * Notes: There is no timer nor any other means by which the requests - * get unblocked other than the low-level driver calling - * scsi_unblock_requests(). + * There is no timer nor any other means by which the requests get unblocked + * other than the low-level driver calling scsi_unblock_requests(). */ void scsi_block_requests(struct Scsi_Host *shost) { @@ -1954,25 +2042,15 @@ void scsi_block_requests(struct Scsi_Host *shost) } EXPORT_SYMBOL(scsi_block_requests); -/* - * Function: scsi_unblock_requests() - * - * Purpose: Utility function used by low-level drivers to allow further - * commands from being queued to the device. - * - * Arguments: shost - Host in question - * - * Returns: Nothing - * - * Lock status: No locks are assumed held. - * - * Notes: There is no timer nor any other means by which the requests - * get unblocked other than the low-level driver calling - * scsi_unblock_requests(). - * - * This is done as an API function so that changes to the - * internals of the scsi mid-layer won't require wholesale - * changes to drivers that use this feature. +/** + * scsi_unblock_requests - Utility function used by low-level drivers to allow + * further commands to be queued to the device. + * @shost: host in question + * + * There is no timer nor any other means by which the requests get unblocked + * other than the low-level driver calling scsi_unblock_requests(). This is done + * as an API function so that changes to the internals of the scsi mid-layer + * won't require wholesale changes to drivers that use this feature. */ void scsi_unblock_requests(struct Scsi_Host *shost) { @@ -1981,24 +2059,9 @@ void scsi_unblock_requests(struct Scsi_Host *shost) } EXPORT_SYMBOL(scsi_unblock_requests); -int __init scsi_init_queue(void) -{ - scsi_sdb_cache = kmem_cache_create("scsi_data_buffer", - sizeof(struct scsi_data_buffer), - 0, 0, NULL); - if (!scsi_sdb_cache) { - printk(KERN_ERR "SCSI: can't init scsi sdb cache\n"); - return -ENOMEM; - } - - return 0; -} - void scsi_exit_queue(void) { kmem_cache_destroy(scsi_sense_cache); - kmem_cache_destroy(scsi_sense_isadma_cache); - kmem_cache_destroy(scsi_sdb_cache); } /** @@ -2006,7 +2069,6 @@ void scsi_exit_queue(void) * @sdev: SCSI device to be queried * @pf: Page format bit (1 == standard, 0 == vendor specific) * @sp: Save page bit (0 == don't save, 1 == save) - * @modepage: mode page being requested * @buffer: request buffer (may not be smaller than eight bytes) * @len: length of request buffer. * @timeout: command timeout @@ -2019,10 +2081,9 @@ void scsi_exit_queue(void) * status on error * */ -int -scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, - unsigned char *buffer, int len, int timeout, int retries, - struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) +int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, + unsigned char *buffer, int len, int timeout, int retries, + struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) { unsigned char cmd[10]; unsigned char *real_buffer; @@ -2031,8 +2092,15 @@ scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, memset(cmd, 0, sizeof(cmd)); cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0); - if (sdev->use_10_for_ms) { - if (len > 65535) + /* + * Use MODE SELECT(10) if the device asked for it or if the mode page + * and the mode select header cannot fit within the maximumm 255 bytes + * of the MODE SELECT(6) command. + */ + if (sdev->use_10_for_ms || + len + 4 > 255 || + data->block_descriptor_length > 255) { + if (len > 65535 - 8) return -EINVAL; real_buffer = kmalloc(8 + len, GFP_KERNEL); if (!real_buffer) @@ -2045,15 +2113,13 @@ scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, real_buffer[3] = data->device_specific; real_buffer[4] = data->longlba ? 0x01 : 0; real_buffer[5] = 0; - real_buffer[6] = data->block_descriptor_length >> 8; - real_buffer[7] = data->block_descriptor_length; + put_unaligned_be16(data->block_descriptor_length, + &real_buffer[6]); cmd[0] = MODE_SELECT_10; - cmd[7] = len >> 8; - cmd[8] = len; + put_unaligned_be16(len, &cmd[7]); } else { - if (len > 255 || data->block_descriptor_length > 255 || - data->longlba) + if (data->longlba) return -EINVAL; real_buffer = kmalloc(4 + len, GFP_KERNEL); @@ -2065,7 +2131,6 @@ scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, real_buffer[1] = data->medium_type; real_buffer[2] = data->device_specific; real_buffer[3] = data->block_descriptor_length; - cmd[0] = MODE_SELECT; cmd[4] = len; @@ -2081,7 +2146,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); /** * scsi_mode_sense - issue a mode sense, falling back from 10 to six bytes if necessary. * @sdev: SCSI device to be queried - * @dbd: set if mode sense will allow block descriptors to be returned + * @dbd: set to prevent mode sense from returning block descriptors * @modepage: mode page being requested * @buffer: request buffer (may not be smaller than eight bytes) * @len: length of request buffer. @@ -2091,9 +2156,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); * @sshdr: place to put sense data (or NULL if no sense to be collected). * must be SCSI_SENSE_BUFFERSIZE big. * - * Returns zero if unsuccessful, or the header offset (either 4 - * or 8 depending on whether a six or ten byte command was - * issued) if successful. + * Returns zero if successful, or a negative error number on failure */ int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, @@ -2118,18 +2181,18 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, sshdr = &my_sshdr; retry: - use_10_for_ms = sdev->use_10_for_ms; + use_10_for_ms = sdev->use_10_for_ms || len > 255; if (use_10_for_ms) { - if (len < 8) - len = 8; + if (len < 8 || len > 65535) + return -EINVAL; cmd[0] = MODE_SENSE_10; - cmd[8] = len; + put_unaligned_be16(len, &cmd[7]); header_length = 8; } else { if (len < 4) - len = 4; + return -EINVAL; cmd[0] = MODE_SENSE; cmd[4] = len; @@ -2140,58 +2203,65 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, sshdr, timeout, retries, NULL); + if (result < 0) + return result; /* This code looks awful: what it's doing is making sure an * ILLEGAL REQUEST sense return identifies the actual command * byte as the problem. MODE_SENSE commands can return * ILLEGAL REQUEST if the code page isn't supported */ - if (use_10_for_ms && !scsi_status_is_good(result) && - driver_byte(result) == DRIVER_SENSE) { + if (!scsi_status_is_good(result)) { if (scsi_sense_valid(sshdr)) { if ((sshdr->sense_key == ILLEGAL_REQUEST) && (sshdr->asc == 0x20) && (sshdr->ascq == 0)) { - /* - * Invalid command operation code + /* + * Invalid command operation code: retry using + * MODE SENSE(6) if this was a MODE SENSE(10) + * request, except if the request mode page is + * too large for MODE SENSE single byte + * allocation length field. */ - sdev->use_10_for_ms = 0; + if (use_10_for_ms) { + if (len > 255) + return -EIO; + sdev->use_10_for_ms = 0; + goto retry; + } + } + if (scsi_status_is_check_condition(result) && + sshdr->sense_key == UNIT_ATTENTION && + retry_count) { + retry_count--; goto retry; } } + return -EIO; + } + if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b && + (modepage == 6 || modepage == 8))) { + /* Initio breakage? */ + header_length = 0; + data->length = 13; + data->medium_type = 0; + data->device_specific = 0; + data->longlba = 0; + data->block_descriptor_length = 0; + } else if (use_10_for_ms) { + data->length = get_unaligned_be16(&buffer[0]) + 2; + data->medium_type = buffer[2]; + data->device_specific = buffer[3]; + data->longlba = buffer[4] & 0x01; + data->block_descriptor_length = get_unaligned_be16(&buffer[6]); + } else { + data->length = buffer[0] + 1; + data->medium_type = buffer[1]; + data->device_specific = buffer[2]; + data->block_descriptor_length = buffer[3]; } + data->header_length = header_length; - if(scsi_status_is_good(result)) { - if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b && - (modepage == 6 || modepage == 8))) { - /* Initio breakage? */ - header_length = 0; - data->length = 13; - data->medium_type = 0; - data->device_specific = 0; - data->longlba = 0; - data->block_descriptor_length = 0; - } else if(use_10_for_ms) { - data->length = buffer[0]*256 + buffer[1] + 2; - data->medium_type = buffer[2]; - data->device_specific = buffer[3]; - data->longlba = buffer[4] & 0x01; - data->block_descriptor_length = buffer[6]*256 - + buffer[7]; - } else { - data->length = buffer[0] + 1; - data->medium_type = buffer[1]; - data->device_specific = buffer[2]; - data->block_descriptor_length = buffer[3]; - } - data->header_length = header_length; - } else if ((status_byte(result) == CHECK_CONDITION) && - scsi_sense_valid(sshdr) && - sshdr->sense_key == UNIT_ATTENTION && retry_count) { - retry_count--; - goto retry; - } - - return result; + return 0; } EXPORT_SYMBOL(scsi_mode_sense); @@ -2253,7 +2323,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) goto illegal; } break; - + case SDEV_RUNNING: switch (oldstate) { case SDEV_CREATED: @@ -2295,6 +2365,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) switch (oldstate) { case SDEV_RUNNING: case SDEV_CREATED_BLOCK: + case SDEV_QUIESCE: case SDEV_OFFLINE: break; default: @@ -2340,6 +2411,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) break; } + sdev->offline_already = false; sdev->sdev_state = state; return 0; @@ -2355,7 +2427,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) EXPORT_SYMBOL(scsi_device_set_state); /** - * sdev_evt_emit - emit a single SCSI device uevent + * scsi_evt_emit - emit a single SCSI device uevent * @sdev: associated SCSI device * @evt: event to emit * @@ -2403,7 +2475,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt) } /** - * sdev_evt_thread - send a uevent for each scsi event + * scsi_evt_thread - send a uevent for each scsi event * @work: work struct for scsi_device * * Dispatch queued events to their associated scsi_device kobjects @@ -2529,15 +2601,13 @@ void sdev_evt_send_simple(struct scsi_device *sdev, EXPORT_SYMBOL_GPL(sdev_evt_send_simple); /** - * scsi_device_quiesce - Block user issued commands. + * scsi_device_quiesce - Block all commands except power management. * @sdev: scsi device to quiesce. * * This works by trying to transition to the SDEV_QUIESCE state * (which must be a legal transition). When the device is in this - * state, only special requests will be accepted, all others will - * be deferred. Since special requests may also be requeued requests, - * a successful return doesn't guarantee the device will be - * totally quiescent. + * state, only power management requests will be accepted, all others will + * be deferred. * * Must be called with user context, may sleep. * @@ -2599,12 +2669,12 @@ void scsi_device_resume(struct scsi_device *sdev) * device deleted during suspend) */ mutex_lock(&sdev->state_mutex); + if (sdev->sdev_state == SDEV_QUIESCE) + scsi_device_set_state(sdev, SDEV_RUNNING); if (sdev->quiesced_by) { sdev->quiesced_by = NULL; blk_clear_pm_only(sdev->request_queue); } - if (sdev->sdev_state == SDEV_QUIESCE) - scsi_device_set_state(sdev, SDEV_RUNNING); mutex_unlock(&sdev->state_mutex); } EXPORT_SYMBOL(scsi_device_resume); @@ -2635,6 +2705,40 @@ scsi_target_resume(struct scsi_target *starget) } EXPORT_SYMBOL(scsi_target_resume); +static int __scsi_internal_device_block_nowait(struct scsi_device *sdev) +{ + if (scsi_device_set_state(sdev, SDEV_BLOCK)) + return scsi_device_set_state(sdev, SDEV_CREATED_BLOCK); + + return 0; +} + +void scsi_start_queue(struct scsi_device *sdev) +{ + if (cmpxchg(&sdev->queue_stopped, 1, 0)) + blk_mq_unquiesce_queue(sdev->request_queue); +} + +static void scsi_stop_queue(struct scsi_device *sdev, bool nowait) +{ + /* + * The atomic variable of ->queue_stopped covers that + * blk_mq_quiesce_queue* is balanced with blk_mq_unquiesce_queue. + * + * However, we still need to wait until quiesce is done + * in case that queue has been stopped. + */ + if (!cmpxchg(&sdev->queue_stopped, 0, 1)) { + if (nowait) + blk_mq_quiesce_queue_nowait(sdev->request_queue); + else + blk_mq_quiesce_queue(sdev->request_queue); + } else { + if (!nowait) + blk_mq_wait_quiesce_done(sdev->request_queue); + } +} + /** * scsi_internal_device_block_nowait - try to transition to the SDEV_BLOCK state * @sdev: device to block @@ -2651,24 +2755,16 @@ EXPORT_SYMBOL(scsi_target_resume); */ int scsi_internal_device_block_nowait(struct scsi_device *sdev) { - struct request_queue *q = sdev->request_queue; - int err = 0; - - err = scsi_device_set_state(sdev, SDEV_BLOCK); - if (err) { - err = scsi_device_set_state(sdev, SDEV_CREATED_BLOCK); - - if (err) - return err; - } + int ret = __scsi_internal_device_block_nowait(sdev); - /* + /* * The device has transitioned to SDEV_BLOCK. Stop the * block layer from calling the midlayer with this device's - * request queue. + * request queue. */ - blk_mq_quiesce_queue_nowait(q); - return 0; + if (!ret) + scsi_stop_queue(sdev, true); + return ret; } EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait); @@ -2689,24 +2785,16 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_block_nowait); */ static int scsi_internal_device_block(struct scsi_device *sdev) { - struct request_queue *q = sdev->request_queue; int err; mutex_lock(&sdev->state_mutex); - err = scsi_internal_device_block_nowait(sdev); + err = __scsi_internal_device_block_nowait(sdev); if (err == 0) - blk_mq_quiesce_queue(q); + scsi_stop_queue(sdev, false); mutex_unlock(&sdev->state_mutex); return err; } - -void scsi_start_queue(struct scsi_device *sdev) -{ - struct request_queue *q = sdev->request_queue; - - blk_mq_unquiesce_queue(q); -} /** * scsi_internal_device_unblock_nowait - resume a device after a block request @@ -2845,6 +2933,56 @@ scsi_target_unblock(struct device *dev, enum scsi_device_state new_state) } EXPORT_SYMBOL_GPL(scsi_target_unblock); +int +scsi_host_block(struct Scsi_Host *shost) +{ + struct scsi_device *sdev; + int ret = 0; + + /* + * Call scsi_internal_device_block_nowait so we can avoid + * calling synchronize_rcu() for each LUN. + */ + shost_for_each_device(sdev, shost) { + mutex_lock(&sdev->state_mutex); + ret = scsi_internal_device_block_nowait(sdev); + mutex_unlock(&sdev->state_mutex); + if (ret) { + scsi_device_put(sdev); + break; + } + } + + /* + * SCSI never enables blk-mq's BLK_MQ_F_BLOCKING flag so + * calling synchronize_rcu() once is enough. + */ + WARN_ON_ONCE(shost->tag_set.flags & BLK_MQ_F_BLOCKING); + + if (!ret) + synchronize_rcu(); + + return ret; +} +EXPORT_SYMBOL_GPL(scsi_host_block); + +int +scsi_host_unblock(struct Scsi_Host *shost, int new_state) +{ + struct scsi_device *sdev; + int ret = 0; + + shost_for_each_device(sdev, shost) { + ret = scsi_internal_device_unblock(sdev, new_state); + if (ret) { + scsi_device_put(sdev); + break; + } + } + return ret; +} +EXPORT_SYMBOL_GPL(scsi_host_unblock); + /** * scsi_kmap_atomic_sg - find and atomically map an sg-elemnt * @sgl: scatter-gather list @@ -2919,6 +3057,78 @@ void sdev_enable_disk_events(struct scsi_device *sdev) } EXPORT_SYMBOL(sdev_enable_disk_events); +static unsigned char designator_prio(const unsigned char *d) +{ + if (d[1] & 0x30) + /* not associated with LUN */ + return 0; + + if (d[3] == 0) + /* invalid length */ + return 0; + + /* + * Order of preference for lun descriptor: + * - SCSI name string + * - NAA IEEE Registered Extended + * - EUI-64 based 16-byte + * - EUI-64 based 12-byte + * - NAA IEEE Registered + * - NAA IEEE Extended + * - EUI-64 based 8-byte + * - SCSI name string (truncated) + * - T10 Vendor ID + * as longer descriptors reduce the likelyhood + * of identification clashes. + */ + + switch (d[1] & 0xf) { + case 8: + /* SCSI name string, variable-length UTF-8 */ + return 9; + case 3: + switch (d[4] >> 4) { + case 6: + /* NAA registered extended */ + return 8; + case 5: + /* NAA registered */ + return 5; + case 4: + /* NAA extended */ + return 4; + case 3: + /* NAA locally assigned */ + return 1; + default: + break; + } + break; + case 2: + switch (d[3]) { + case 16: + /* EUI64-based, 16 byte */ + return 7; + case 12: + /* EUI64-based, 12 byte */ + return 6; + case 8: + /* EUI64-based, 8 byte */ + return 3; + default: + break; + } + break; + case 1: + /* T10 vendor ID */ + return 1; + default: + break; + } + + return 0; +} + /** * scsi_vpd_lun_id - return a unique device identification * @sdev: SCSI device @@ -2935,7 +3145,7 @@ EXPORT_SYMBOL(sdev_enable_disk_events); */ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) { - u8 cur_id_type = 0xff; + u8 cur_id_prio = 0; u8 cur_id_size = 0; const unsigned char *d, *cur_id_str; const struct scsi_vpd *vpd_pg83; @@ -2948,20 +3158,6 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) return -ENXIO; } - /* - * Look for the correct descriptor. - * Order of preference for lun descriptor: - * - SCSI name string - * - NAA IEEE Registered Extended - * - EUI-64 based 16-byte - * - EUI-64 based 12-byte - * - NAA IEEE Registered - * - NAA IEEE Extended - * - T10 Vendor ID - * as longer descriptors reduce the likelyhood - * of identification clashes. - */ - /* The id string must be at least 20 bytes + terminating NULL byte */ if (id_len < 21) { rcu_read_unlock(); @@ -2969,39 +3165,32 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) } memset(id, 0, id_len); - d = vpd_pg83->data + 4; - while (d < vpd_pg83->data + vpd_pg83->len) { - /* Skip designators not referring to the LUN */ - if ((d[1] & 0x30) != 0x00) - goto next_desig; + for (d = vpd_pg83->data + 4; + d < vpd_pg83->data + vpd_pg83->len; + d += d[3] + 4) { + u8 prio = designator_prio(d); + + if (prio == 0 || cur_id_prio > prio) + continue; switch (d[1] & 0xf) { case 0x1: /* T10 Vendor ID */ if (cur_id_size > d[3]) break; - /* Prefer anything */ - if (cur_id_type > 0x01 && cur_id_type != 0xff) - break; + cur_id_prio = prio; cur_id_size = d[3]; if (cur_id_size + 4 > id_len) cur_id_size = id_len - 4; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; id_size = snprintf(id, id_len, "t10.%*pE", cur_id_size, cur_id_str); break; case 0x2: /* EUI-64 */ - if (cur_id_size > d[3]) - break; - /* Prefer NAA IEEE Registered Extended */ - if (cur_id_type == 0x3 && - cur_id_size == d[3]) - break; + cur_id_prio = prio; cur_id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; switch (cur_id_size) { case 8: id_size = snprintf(id, id_len, @@ -3019,17 +3208,14 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) cur_id_str); break; default: - cur_id_size = 0; break; } break; case 0x3: /* NAA */ - if (cur_id_size > d[3]) - break; + cur_id_prio = prio; cur_id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; switch (cur_id_size) { case 8: id_size = snprintf(id, id_len, @@ -3042,32 +3228,29 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) cur_id_str); break; default: - cur_id_size = 0; break; } break; case 0x8: /* SCSI name string */ - if (cur_id_size + 4 > d[3]) + if (cur_id_size > d[3]) break; /* Prefer others for truncated descriptor */ - if (cur_id_size && d[3] > id_len) - break; + if (d[3] > id_len) { + prio = 2; + if (cur_id_prio > prio) + break; + } + cur_id_prio = prio; cur_id_size = id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; if (cur_id_size >= id_len) cur_id_size = id_len - 1; memcpy(id, cur_id_str, cur_id_size); - /* Decrease priority for truncated descriptor */ - if (cur_id_size != id_size) - cur_id_size = 6; break; default: break; } -next_desig: - d += d[3] + 4; } rcu_read_unlock(); @@ -3121,3 +3304,20 @@ int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) return group_id; } EXPORT_SYMBOL(scsi_vpd_tpg_id); + +/** + * scsi_build_sense - build sense data for a command + * @scmd: scsi command for which the sense should be formatted + * @desc: Sense format (non-zero == descriptor format, + * 0 == fixed format) + * @key: Sense key + * @asc: Additional sense code + * @ascq: Additional sense code qualifier + * + **/ +void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq) +{ + scsi_build_sense_buffer(desc, scmd->sense_buffer, key, asc, ascq); + scmd->result = SAM_STAT_CHECK_CONDITION; +} +EXPORT_SYMBOL_GPL(scsi_build_sense); |