Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[platform/kernel/linux-starfive.git] / drivers / scsi / scsi_lib.c
index e30bc51..8d18cc7 100644 (file)
@@ -213,7 +213,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
                 int *resid)
 {
        struct request *req;
-       struct scsi_request *rq;
+       struct scsi_cmnd *scmd;
        int ret;
 
        req = scsi_alloc_request(sdev->request_queue,
@@ -223,17 +223,16 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       rq = scsi_req(req);
-
        if (bufflen) {
                ret = blk_rq_map_kern(sdev->request_queue, req,
                                      buffer, bufflen, GFP_NOIO);
                if (ret)
                        goto out;
        }
-       rq->cmd_len = COMMAND_SIZE(cmd[0]);
-       memcpy(rq->cmd, cmd, rq->cmd_len);
-       rq->retries = retries;
+       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;
@@ -249,16 +248,17 @@ 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_mq_free_request(req);
 
@@ -874,9 +874,8 @@ 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);
@@ -957,13 +956,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        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.
@@ -1124,13 +1116,10 @@ EXPORT_SYMBOL(scsi_alloc_sgtables);
 static void scsi_initialize_rq(struct request *rq)
 {
        struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
-       struct scsi_request *req = &cmd->req;
-
-       memset(req->__cmd, 0, sizeof(req->__cmd));
-       req->cmd = req->__cmd;
-       req->cmd_len = BLK_MAX_CDB;
-       req->sense_len = 0;
 
+       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;
@@ -1163,45 +1152,16 @@ static void scsi_cleanup_rq(struct request *rq)
 /* 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 = scsi_cmd_to_rq(cmd);
-       unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS;
-       unsigned long jiffies_at_alloc;
-       int retries, to_clear;
-       bool in_flight;
-       int budget_token = cmd->budget_token;
-
-       if (!blk_rq_is_passthrough(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. Only clear
-        * the driver-private command data if the LLD does not supply a
-        * function to initialize that data.
-        */
-       to_clear = sizeof(*cmd) - sizeof(cmd->req);
-       if (!dev->host->hostt->init_cmd_priv)
-               to_clear += dev->host->hostt->cmd_size;
-       memset((char *)cmd + sizeof(cmd->req), 0, to_clear);
-
        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);
-       cmd->budget_token = budget_token;
-
 }
 
 static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev,
@@ -1225,10 +1185,7 @@ 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;
 }
 
@@ -1586,10 +1543,33 @@ 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->eh_eflags = 0;
+       cmd->allowed = 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);
@@ -1620,13 +1600,14 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
                        return ret;
        }
 
-       cmd->cmnd = scsi_req(req)->cmd = scsi_req(req)->__cmd;
-       memset(cmd->cmnd, 0, BLK_MAX_CDB);
+       memset(cmd->cmnd, 0, sizeof(cmd->cmnd));
        return scsi_cmd_to_driver(cmd)->init_command(cmd);
 }
 
-void scsi_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;
@@ -1641,10 +1622,25 @@ void scsi_done(struct scsi_cmnd *cmd)
        if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))
                return;
        trace_scsi_dispatch_cmd_done(cmd);
-       blk_mq_complete_request(scsi_cmd_to_rq(cmd));
+
+       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);
 
+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 scsi_device *sdev = q->queuedata;
@@ -1772,15 +1768,15 @@ out_put_budget:
                        ret = BLK_STS_DEV_RESOURCE;
                break;
        case BLK_STS_AGAIN:
-               scsi_req(req)->result = DID_BUS_BUSY << 16;
+               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
@@ -1814,7 +1810,6 @@ static int scsi_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
                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) +