summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-01-27 09:46:29 +0100
committerJens Axboe <axboe@fb.com>2017-01-27 15:08:35 -0700
commit82ed4db499b8598f16f8871261bff088d6b0597f (patch)
treee1cc0a433bf5ae2b9723837291617bdfeeb61816 /drivers/scsi
parent8ae94eb65be9425af4d57a4f4cfebfdf03081e93 (diff)
downloadlinux-stable-82ed4db499b8598f16f8871261bff088d6b0597f.tar.gz
linux-stable-82ed4db499b8598f16f8871261bff088d6b0597f.tar.bz2
linux-stable-82ed4db499b8598f16f8871261bff088d6b0597f.zip
block: split scsi_request out of struct request
And require all drivers that want to support BLOCK_PC to allocate it as the first thing of their private data. To support this the legacy IDE and BSG code is switched to set cmd_size on their queues to let the block layer allocate the additional space. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libfc/fc_lport.c2
-rw-r--r--drivers/scsi/libsas/sas_expander.c8
-rw-r--r--drivers/scsi/libsas/sas_host_smp.c38
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_transport.c8
-rw-r--r--drivers/scsi/osd/osd_initiator.c19
-rw-r--r--drivers/scsi/osst.c15
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c2
-rw-r--r--drivers/scsi/scsi_error.c22
-rw-r--r--drivers/scsi/scsi_lib.c51
-rw-r--r--drivers/scsi/scsi_transport_sas.c5
-rw-r--r--drivers/scsi/sd.c4
-rw-r--r--drivers/scsi/sg.c30
-rw-r--r--drivers/scsi/st.c22
15 files changed, 127 insertions, 107 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 919736a74ffa..aa76f36abe03 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -2095,7 +2095,7 @@ int fc_lport_bsg_request(struct bsg_job *job)
bsg_reply->reply_payload_rcv_len = 0;
if (rsp)
- rsp->resid_len = job->reply_payload.payload_len;
+ scsi_req(rsp)->resid_len = job->reply_payload.payload_len;
mutex_lock(&lport->lp_mutex);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 022bb6e10d98..570b2cb2da43 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -2174,12 +2174,12 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
bio_data(rsp->bio), blk_rq_bytes(rsp));
if (ret > 0) {
/* positive number is the untransferred residual */
- rsp->resid_len = ret;
- req->resid_len = 0;
+ scsi_req(rsp)->resid_len = ret;
+ scsi_req(req)->resid_len = 0;
ret = 0;
} else if (ret == 0) {
- rsp->resid_len = 0;
- req->resid_len = 0;
+ scsi_req(rsp)->resid_len = 0;
+ scsi_req(req)->resid_len = 0;
}
return ret;
diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c
index d24792575169..45cbbc44f4d7 100644
--- a/drivers/scsi/libsas/sas_host_smp.c
+++ b/drivers/scsi/libsas/sas_host_smp.c
@@ -274,15 +274,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
switch (req_data[1]) {
case SMP_REPORT_GENERAL:
- req->resid_len -= 8;
- rsp->resid_len -= 32;
+ scsi_req(req)->resid_len -= 8;
+ scsi_req(rsp)->resid_len -= 32;
resp_data[2] = SMP_RESP_FUNC_ACC;
resp_data[9] = sas_ha->num_phys;
break;
case SMP_REPORT_MANUF_INFO:
- req->resid_len -= 8;
- rsp->resid_len -= 64;
+ scsi_req(req)->resid_len -= 8;
+ scsi_req(rsp)->resid_len -= 64;
resp_data[2] = SMP_RESP_FUNC_ACC;
memcpy(resp_data + 12, shost->hostt->name,
SAS_EXPANDER_VENDOR_ID_LEN);
@@ -295,13 +295,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_DISCOVER:
- req->resid_len -= 16;
- if ((int)req->resid_len < 0) {
- req->resid_len = 0;
+ scsi_req(req)->resid_len -= 16;
+ if ((int)scsi_req(req)->resid_len < 0) {
+ scsi_req(req)->resid_len = 0;
error = -EINVAL;
goto out;
}
- rsp->resid_len -= 56;
+ scsi_req(rsp)->resid_len -= 56;
sas_host_smp_discover(sas_ha, resp_data, req_data[9]);
break;
@@ -311,13 +311,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_REPORT_PHY_SATA:
- req->resid_len -= 16;
- if ((int)req->resid_len < 0) {
- req->resid_len = 0;
+ scsi_req(req)->resid_len -= 16;
+ if ((int)scsi_req(req)->resid_len < 0) {
+ scsi_req(req)->resid_len = 0;
error = -EINVAL;
goto out;
}
- rsp->resid_len -= 60;
+ scsi_req(rsp)->resid_len -= 60;
sas_report_phy_sata(sas_ha, resp_data, req_data[9]);
break;
@@ -331,15 +331,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
int to_write = req_data[4];
if (blk_rq_bytes(req) < base_frame_size + to_write * 4 ||
- req->resid_len < base_frame_size + to_write * 4) {
+ scsi_req(req)->resid_len < base_frame_size + to_write * 4) {
resp_data[2] = SMP_RESP_INV_FRM_LEN;
break;
}
to_write = sas_host_smp_write_gpio(sas_ha, resp_data, req_data[2],
req_data[3], to_write, &req_data[8]);
- req->resid_len -= base_frame_size + to_write * 4;
- rsp->resid_len -= 8;
+ scsi_req(req)->resid_len -= base_frame_size + to_write * 4;
+ scsi_req(rsp)->resid_len -= 8;
break;
}
@@ -348,13 +348,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break;
case SMP_PHY_CONTROL:
- req->resid_len -= 44;
- if ((int)req->resid_len < 0) {
- req->resid_len = 0;
+ scsi_req(req)->resid_len -= 44;
+ if ((int)scsi_req(req)->resid_len < 0) {
+ scsi_req(req)->resid_len = 0;
error = -EINVAL;
goto out;
}
- rsp->resid_len -= 8;
+ scsi_req(rsp)->resid_len -= 8;
sas_phy_control(sas_ha, req_data[9], req_data[10],
req_data[32] >> 4, req_data[33] >> 4,
resp_data);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 7f1d5785bc30..e7a7a704a315 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -2057,10 +2057,10 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
ioc->name, __func__,
le16_to_cpu(mpi_reply->ResponseDataLength)));
- memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
- req->sense_len = sizeof(*mpi_reply);
- req->resid_len = 0;
- rsp->resid_len -=
+ memcpy(scsi_req(req)->sense, mpi_reply, sizeof(*mpi_reply));
+ scsi_req(req)->sense_len = sizeof(*mpi_reply);
+ scsi_req(req)->resid_len = 0;
+ scsi_req(rsp)->resid_len -=
le16_to_cpu(mpi_reply->ResponseDataLength);
/* check if the resp needs to be copied from the allocated
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index ef99f62831fb..fcb040eebf47 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -48,6 +48,7 @@
#include <scsi/osd_sense.h>
#include <scsi/scsi_device.h>
+#include <scsi/scsi_request.h>
#include "osd_debug.h"
@@ -477,11 +478,13 @@ static void _set_error_resid(struct osd_request *or, struct request *req,
{
or->async_error = error;
or->req_errors = req->errors ? : error;
- or->sense_len = req->sense_len;
+ or->sense_len = scsi_req(req)->sense_len;
+ if (or->sense_len)
+ memcpy(or->sense, scsi_req(req)->sense, or->sense_len);
if (or->out.req)
- or->out.residual = or->out.req->resid_len;
+ or->out.residual = scsi_req(or->out.req)->resid_len;
if (or->in.req)
- or->in.residual = or->in.req->resid_len;
+ or->in.residual = scsi_req(or->in.req)->resid_len;
}
int osd_execute_request(struct osd_request *or)
@@ -1565,7 +1568,7 @@ static struct request *_make_request(struct request_queue *q, bool has_write,
req = blk_get_request(q, has_write ? WRITE : READ, flags);
if (IS_ERR(req))
return req;
- blk_rq_set_block_pc(req);
+ scsi_req_init(req);
for_each_bio(bio) {
struct bio *bounce_bio = bio;
@@ -1599,8 +1602,6 @@ static int _init_blk_request(struct osd_request *or,
req->timeout = or->timeout;
req->retries = or->retries;
- req->sense = or->sense;
- req->sense_len = 0;
if (has_out) {
or->out.req = req;
@@ -1612,7 +1613,7 @@ static int _init_blk_request(struct osd_request *or,
ret = PTR_ERR(req);
goto out;
}
- blk_rq_set_block_pc(req);
+ scsi_req_init(req);
or->in.req = or->request->next_rq = req;
}
} else if (has_in)
@@ -1699,8 +1700,8 @@ int osd_finalize_request(struct osd_request *or,
osd_sec_sign_cdb(&or->cdb, cap_key);
- or->request->cmd = or->cdb.buff;
- or->request->cmd_len = _osd_req_cdb_len(or);
+ scsi_req(or->request)->cmd = or->cdb.buff;
+ scsi_req(or->request)->cmd_len = _osd_req_cdb_len(or);
return 0;
}
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index e8196c55b633..d314aa5c71cf 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -322,6 +322,7 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
/* Wakeup from interrupt */
static void osst_end_async(struct request *req, int update)
{
+ struct scsi_request *rq = scsi_req(req);
struct osst_request *SRpnt = req->end_io_data;
struct osst_tape *STp = SRpnt->stp;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
@@ -330,6 +331,8 @@ static void osst_end_async(struct request *req, int update)
#if DEBUG
STp->write_pending = 0;
#endif
+ if (rq->sense_len)
+ memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
if (SRpnt->waiting)
complete(SRpnt->waiting);
@@ -357,6 +360,7 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
int use_sg, int timeout, int retries)
{
struct request *req;
+ struct scsi_request *rq;
struct page **pages = NULL;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
@@ -367,7 +371,8 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
if (IS_ERR(req))
return DRIVER_ERROR << 24;
- blk_rq_set_block_pc(req);
+ rq = scsi_req(req);
+ scsi_req_init(req);
req->rq_flags |= RQF_QUIET;
SRpnt->bio = NULL;
@@ -404,11 +409,9 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
goto free_req;
}
- req->cmd_len = cmd_len;
- memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
- memcpy(req->cmd, cmd, req->cmd_len);
- req->sense = SRpnt->sense;
- req->sense_len = 0;
+ rq->cmd_len = cmd_len;
+ memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
+ memcpy(rq->cmd, cmd, rq->cmd_len);
req->timeout = timeout;
req->retries = retries;
req->end_io_data = SRpnt;
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 1bf8061ff803..40ca75bbcb9d 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -921,7 +921,7 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
sizeof(response) + sizeof(uint8_t);
- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+ fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) +
sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, response, sizeof(response));
fw_sts_ptr += sizeof(response);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index dc88a09f9043..67e157d81da8 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1468,7 +1468,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
type, sp->handle, comp_status, fw_status[1], fw_status[2],
le16_to_cpu(((struct els_sts_entry_24xx *)
pkt)->total_byte_count));
- fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+ fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) +
+ sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
else {
@@ -1482,7 +1483,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
pkt)->error_subcode_2));
res = DID_ERROR << 16;
bsg_reply->reply_payload_rcv_len = 0;
- fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
+ fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) +
+ sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056,
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 02f1de18bc2b..96c33e292eba 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2244,7 +2244,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
memcpy(fstatus.reserved_3,
pkt->reserved_2, 20 * sizeof(uint8_t));
- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+ fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) +
sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, (uint8_t *)&fstatus,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 7c084600827b..4b40f746d534 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1968,6 +1968,7 @@ static void eh_lock_door_done(struct request *req, int uptodate)
static void scsi_eh_lock_door(struct scsi_device *sdev)
{
struct request *req;
+ struct scsi_request *rq;
/*
* blk_get_request with GFP_KERNEL (__GFP_RECLAIM) sleeps until a
@@ -1976,17 +1977,16 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
if (IS_ERR(req))
return;
+ rq = scsi_req(req);
+ scsi_req_init(req);
- blk_rq_set_block_pc(req);
-
- req->cmd[0] = ALLOW_MEDIUM_REMOVAL;
- req->cmd[1] = 0;
- req->cmd[2] = 0;
- req->cmd[3] = 0;
- req->cmd[4] = SCSI_REMOVAL_PREVENT;
- req->cmd[5] = 0;
-
- req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+ rq->cmd[0] = ALLOW_MEDIUM_REMOVAL;
+ rq->cmd[1] = 0;
+ rq->cmd[2] = 0;
+ rq->cmd[3] = 0;
+ rq->cmd[4] = SCSI_REMOVAL_PREVENT;
+ rq->cmd[5] = 0;
+ rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
req->rq_flags |= RQF_QUIET;
req->timeout = 10 * HZ;
@@ -2355,7 +2355,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
scmd = (struct scsi_cmnd *)(rq + 1);
scsi_init_command(dev, scmd);
scmd->request = rq;
- scmd->cmnd = rq->cmd;
+ scmd->cmnd = scsi_req(rq)->cmd;
scmd->scsi_done = scsi_reset_provider_done_command;
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 81ff5ad23b83..8188e5c71f75 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -220,21 +220,21 @@ static int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
{
struct request *req;
int write = (data_direction == DMA_TO_DEVICE);
+ struct scsi_request *rq;
int ret = DRIVER_ERROR << 24;
req = blk_get_request(sdev->request_queue, write, __GFP_RECLAIM);
if (IS_ERR(req))
return ret;
- blk_rq_set_block_pc(req);
+ rq = scsi_req(req);
+ scsi_req_init(req);
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
buffer, bufflen, __GFP_RECLAIM))
goto out;
- req->cmd_len = COMMAND_SIZE(cmd[0]);
- memcpy(req->cmd, cmd, req->cmd_len);
- req->sense = sense;
- req->sense_len = 0;
+ rq->cmd_len = COMMAND_SIZE(cmd[0]);
+ memcpy(rq->cmd, cmd, rq->cmd_len);
req->retries = retries;
req->timeout = timeout;
req->cmd_flags |= flags;
@@ -251,11 +251,13 @@ static 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(req->resid_len > 0 && req->resid_len <= bufflen))
- memset(buffer + (bufflen - req->resid_len), 0, req->resid_len);
+ if (unlikely(rq->resid_len > 0 && rq->resid_len <= bufflen))
+ memset(buffer + (bufflen - rq->resid_len), 0, rq->resid_len);
if (resid)
- *resid = req->resid_len;
+ *resid = rq->resid_len;
+ if (sense && rq->sense_len)
+ memcpy(sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
ret = req->errors;
out:
blk_put_request(req);
@@ -806,16 +808,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */
if (result) {
- if (sense_valid && req->sense) {
+ if (sense_valid) {
/*
* SG_IO wants current and deferred errors
*/
- int len = 8 + cmd->sense_buffer[7];
-
- if (len > SCSI_SENSE_BUFFERSIZE)
- len = SCSI_SENSE_BUFFERSIZE;
- memcpy(req->sense, cmd->sense_buffer, len);
- req->sense_len = len;
+ scsi_req(req)->sense_len =
+ min(8 + cmd->sense_buffer[7],
+ SCSI_SENSE_BUFFERSIZE);
}
if (!sense_deferred)
error = __scsi_error_from_host_byte(cmd, result);
@@ -825,14 +824,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
*/
req->errors = cmd->result;
- req->resid_len = scsi_get_resid(cmd);
+ scsi_req(req)->resid_len = scsi_get_resid(cmd);
if (scsi_bidi_cmnd(cmd)) {
/*
* Bidi commands Must be complete as a whole,
* both sides at once.
*/
- req->next_rq->resid_len = scsi_in(cmd)->resid;
+ scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
if (scsi_end_request(req, 0, blk_rq_bytes(req),
blk_rq_bytes(req->next_rq)))
BUG();
@@ -1165,7 +1164,10 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd)
void *prot = cmd->prot_sdb;
unsigned long flags;
- memset(cmd, 0, sizeof(*cmd));
+ /* zero out the cmd, except for the embedded scsi_request */
+ memset((char *)cmd + sizeof(cmd->req), 0,
+ sizeof(*cmd) - sizeof(cmd->req));
+
cmd->device = dev;
cmd->sense_buffer = buf;
cmd->prot_sdb = prot;
@@ -1197,7 +1199,8 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
memset(&cmd->sdb, 0, sizeof(cmd->sdb));
}
- cmd->cmd_len = req->cmd_len;
+ cmd->cmd_len = scsi_req(req)->cmd_len;
+ cmd->cmnd = scsi_req(req)->cmd;
cmd->transfersize = blk_rq_bytes(req);
cmd->allowed = req->retries;
return BLKPREP_OK;
@@ -1217,6 +1220,7 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
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);
}
@@ -1355,7 +1359,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
cmd->tag = req->tag;
cmd->request = req;
- cmd->cmnd = req->cmd;
cmd->prot_op = SCSI_PROT_NORMAL;
ret = scsi_setup_cmnd(sdev, req);
@@ -1874,7 +1877,9 @@ static int scsi_mq_prep_fn(struct request *req)
unsigned char *sense_buf = cmd->sense_buffer;
struct scatterlist *sg;
- memset(cmd, 0, sizeof(struct scsi_cmnd));
+ /* zero out the cmd, except for the embedded scsi_request */
+ memset((char *)cmd + sizeof(cmd->req), 0,
+ sizeof(*cmd) - sizeof(cmd->req));
req->special = cmd;
@@ -1884,7 +1889,6 @@ static int scsi_mq_prep_fn(struct request *req)
cmd->tag = req->tag;
- cmd->cmnd = req->cmd;
cmd->prot_op = SCSI_PROT_NORMAL;
INIT_LIST_HEAD(&cmd->list);
@@ -1959,7 +1963,6 @@ static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
if (!scsi_host_queue_ready(q, shost, sdev))
goto out_dec_target_busy;
-
if (!(req->rq_flags & RQF_DONTPREP)) {
ret = prep_to_mq(scsi_mq_prep_fn(req));
if (ret != BLK_MQ_RQ_QUEUE_OK)
@@ -2036,6 +2039,7 @@ static int scsi_init_request(void *data, struct request *rq,
scsi_alloc_sense_buffer(shost, GFP_KERNEL, numa_node);
if (!cmd->sense_buffer)
return -ENOMEM;
+ cmd->req.sense = cmd->sense_buffer;
return 0;
}
@@ -2125,6 +2129,7 @@ static int scsi_init_rq(struct request_queue *q, struct request *rq, gfp_t gfp)
cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp, NUMA_NO_NODE);
if (!cmd->sense_buffer)
goto fail;
+ cmd->req.sense = cmd->sense_buffer;
if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 60b651bfaa01..126a5ee00987 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -33,6 +33,7 @@
#include <linux/bsg.h>
#include <scsi/scsi.h>
+#include <scsi/scsi_request.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
@@ -177,6 +178,10 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
while ((req = blk_fetch_request(q)) != NULL) {
spin_unlock_irq(q->queue_lock);
+ scsi_req(req)->resid_len = blk_rq_bytes(req);
+ if (req->next_rq)
+ scsi_req(req->next_rq)->resid_len =
+ blk_rq_bytes(req->next_rq);
handler = to_sas_internal(shost->transportt)->f->smp_handler;
ret = handler(shost, rphy, req);
req->errors = ret;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0b09638fa39b..c779986edb43 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -781,7 +781,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
rq->special_vec.bv_len = len;
rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
- rq->resid_len = len;
+ scsi_req(rq)->resid_len = len;
ret = scsi_init_io(cmd);
out:
@@ -1164,7 +1164,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
__free_page(rq->special_vec.bv_page);
- if (SCpnt->cmnd != rq->cmd) {
+ if (SCpnt->cmnd != scsi_req(rq)->cmd) {
mempool_free(SCpnt->cmnd, sd_cdb_pool);
SCpnt->cmnd = NULL;
SCpnt->cmd_len = 0;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index dbe5b4b95df0..226a8def7a8b 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -781,9 +781,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
}
if (atomic_read(&sdp->detaching)) {
if (srp->bio) {
- if (srp->rq->cmd != srp->rq->__cmd)
- kfree(srp->rq->cmd);
-
+ scsi_req_free_cmd(scsi_req(srp->rq));
blk_end_request_all(srp->rq, -EIO);
srp->rq = NULL;
}
@@ -1279,6 +1277,7 @@ static void
sg_rq_end_io(struct request *rq, int uptodate)
{
struct sg_request *srp = rq->end_io_data;
+ struct scsi_request *req = scsi_req(rq);
Sg_device *sdp;
Sg_fd *sfp;
unsigned long iflags;
@@ -1297,9 +1296,9 @@ sg_rq_end_io(struct request *rq, int uptodate)
if (unlikely(atomic_read(&sdp->detaching)))
pr_info("%s: device detaching\n", __func__);
- sense = rq->sense;
+ sense = req->sense;
result = rq->errors;
- resid = rq->resid_len;
+ resid = req->resid_len;
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp,
"sg_cmd_done: pack_id=%d, res=0x%x\n",
@@ -1333,6 +1332,10 @@ sg_rq_end_io(struct request *rq, int uptodate)
sdp->device->changed = 1;
}
}
+
+ if (req->sense_len)
+ memcpy(srp->sense_b, req->sense, SCSI_SENSE_BUFFERSIZE);
+
/* Rely on write phase to clean out srp status values, so no "else" */
/*
@@ -1342,8 +1345,7 @@ sg_rq_end_io(struct request *rq, int uptodate)
* blk_rq_unmap_user() can be called from user context.
*/
srp->rq = NULL;
- if (rq->cmd != rq->__cmd)
- kfree(rq->cmd);
+ scsi_req_free_cmd(scsi_req(rq));
__blk_put_request(rq->q, rq);
write_lock_irqsave(&sfp->rq_list_lock, iflags);
@@ -1658,6 +1660,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
{
int res;
struct request *rq;
+ struct scsi_request *req;
Sg_fd *sfp = srp->parentfp;
sg_io_hdr_t *hp = &srp->header;
int dxfer_len = (int) hp->dxfer_len;
@@ -1700,17 +1703,17 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
kfree(long_cmdp);
return PTR_ERR(rq);
}
+ req = scsi_req(rq);
- blk_rq_set_block_pc(rq);
+ scsi_req_init(rq);
if (hp->cmd_len > BLK_MAX_CDB)
- rq->cmd = long_cmdp;
- memcpy(rq->cmd, cmd, hp->cmd_len);
- rq->cmd_len = hp->cmd_len;
+ req->cmd = long_cmdp;
+ memcpy(req->cmd, cmd, hp->cmd_len);
+ req->cmd_len = hp->cmd_len;
srp->rq = rq;
rq->end_io_data = srp;
- rq->sense = srp->sense_b;
rq->retries = SG_DEFAULT_RETRIES;
if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
@@ -1786,8 +1789,7 @@ sg_finish_rem_req(Sg_request *srp)
ret = blk_rq_unmap_user(srp->bio);
if (srp->rq) {
- if (srp->rq->cmd != srp->rq->__cmd)
- kfree(srp->rq->cmd);
+ scsi_req_free_cmd(scsi_req(srp->rq));
blk_put_request(srp->rq);
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 5f35b863e1a7..4af900100a24 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -475,7 +475,7 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req)
ktime_t now;
now = ktime_get();
- if (req->cmd[0] == WRITE_6) {
+ if (scsi_req(req)->cmd[0] == WRITE_6) {
now = ktime_sub(now, STp->stats->write_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_write_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
@@ -489,7 +489,7 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req)
} else
atomic64_add(atomic_read(&STp->stats->last_write_size),
&STp->stats->write_byte_cnt);
- } else if (req->cmd[0] == READ_6) {
+ } else if (scsi_req(req)->cmd[0] == READ_6) {
now = ktime_sub(now, STp->stats->read_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_read_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
@@ -514,15 +514,18 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req)
static void st_scsi_execute_end(struct request *req, int uptodate)
{
struct st_request *SRpnt = req->end_io_data;
+ struct scsi_request *rq = scsi_req(req);
struct scsi_tape *STp = SRpnt->stp;
struct bio *tmp;
STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
- STp->buffer->cmdstat.residual = req->resid_len;
+ STp->buffer->cmdstat.residual = rq->resid_len;
st_do_stats(STp, req);
tmp = SRpnt->bio;
+ if (rq->sense_len)
+ memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
if (SRpnt->waiting)
complete(SRpnt->waiting);
@@ -535,6 +538,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
int timeout, int retries)
{
struct request *req;
+ struct scsi_request *rq;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
int err = 0;
int write = (data_direction == DMA_TO_DEVICE);
@@ -544,8 +548,8 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
GFP_KERNEL);
if (IS_ERR(req))
return DRIVER_ERROR << 24;
-
- blk_rq_set_block_pc(req);
+ rq = scsi_req(req);
+ scsi_req_init(req);
req->rq_flags |= RQF_QUIET;
mdata->null_mapped = 1;
@@ -571,11 +575,9 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
}
SRpnt->bio = req->bio;
- req->cmd_len = COMMAND_SIZE(cmd[0]);
- memset(req->cmd, 0, BLK_MAX_CDB);
- memcpy(req->cmd, cmd, req->cmd_len);
- req->sense = SRpnt->sense;
- req->sense_len = 0;
+ rq->cmd_len = COMMAND_SIZE(cmd[0]);
+ memset(rq->cmd, 0, BLK_MAX_CDB);
+ memcpy(rq->cmd, cmd, rq->cmd_len);
req->timeout = timeout;
req->retries = retries;
req->end_io_data = SRpnt;