@@ -105,8 +105,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
rq->__sector = (sector_t) -1;
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
- rq->cmd = rq->__cmd;
- rq->cmd_len = BLK_MAX_CDB;
rq->tag = -1;
rq->start_time = jiffies;
set_start_time_ns(rq);
@@ -149,7 +147,7 @@ void blk_dump_rq_flags(struct request *rq, char *msg)
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
printk(KERN_INFO " cdb: ");
for (bit = 0; bit < BLK_MAX_CDB; bit++)
- printk("%02x ", rq->cmd[bit]);
+ printk("%02x ", rq->block_pc->cmd[bit]);
printk("\n");
}
}
@@ -1253,8 +1251,6 @@ struct request *blk_make_request(struct request_queue *q, struct bio *bio,
if (IS_ERR(rq))
return rq;
- blk_rq_set_block_pc(rq);
-
for_each_bio(bio) {
struct bio *bounce_bio = bio;
int ret;
@@ -1274,15 +1270,24 @@ EXPORT_SYMBOL(blk_make_request);
/**
* blk_rq_set_block_pc - initialize a request to type BLOCK_PC
* @rq: request to be initialized
+ * @cmd_len: length of the CDB
+ * @gfp: kmalloc flags
*
*/
-void blk_rq_set_block_pc(struct request *rq)
+int blk_rq_set_block_pc(struct request *rq, unsigned short cmd_len,
+ u8 *sense, gfp_t gfp)
{
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->__data_len = 0;
rq->__sector = (sector_t) -1;
rq->bio = rq->biotail = NULL;
- memset(rq->__cmd, 0, sizeof(rq->__cmd));
+
+ rq->block_pc = kzalloc(sizeof(*rq->block_pc) + cmd_len, gfp);
+ if (!rq->block_pc)
+ return -ENOMEM;
+ rq->block_pc->cmd_len = cmd_len;
+ rq->block_pc->sense = sense;
+ return 0;
}
EXPORT_SYMBOL(blk_rq_set_block_pc);
@@ -1379,6 +1384,10 @@ void __blk_put_request(struct request_queue *q, struct request *req)
if (unlikely(!q))
return;
+ /* could also be other type-specific data */
+ if (req->block_pc)
+ kfree(req->block_pc);
+
if (q->mq_ops) {
blk_mq_free_request(req);
return;
@@ -10,11 +10,6 @@
#include "blk.h"
-/*
- * for max sense size
- */
-#include <scsi/scsi_cmnd.h>
-
/**
* blk_end_sync_rq - executes a completion event on a request
* @rq: request to complete
@@ -100,16 +95,9 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
struct request *rq, int at_head)
{
DECLARE_COMPLETION_ONSTACK(wait);
- char sense[SCSI_SENSE_BUFFERSIZE];
int err = 0;
unsigned long hang_check;
- if (!rq->sense) {
- memset(sense, 0, sizeof(sense));
- rq->sense = sense;
- rq->sense_len = 0;
- }
-
rq->end_io_data = &wait;
blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
@@ -123,11 +111,6 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
if (rq->errors)
err = -EIO;
- if (rq->sense == sense) {
- rq->sense = NULL;
- rq->sense_len = 0;
- }
-
return err;
}
EXPORT_SYMBOL(blk_execute_rq);
@@ -210,12 +210,8 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
/* tag was already set */
rq->errors = 0;
- rq->cmd = rq->__cmd;
-
rq->extra_len = 0;
- rq->sense_len = 0;
rq->resid_len = 0;
- rq->sense = NULL;
INIT_LIST_HEAD(&rq->timeout_list);
rq->timeout = 0;
@@ -59,9 +59,9 @@ void bsg_job_done(struct bsg_job *job, int result,
err = job->req->errors = result;
if (err < 0)
/* we're only returning the result field in the reply */
- job->req->sense_len = sizeof(u32);
+ job->req->block_pc->sense_len = sizeof(u32);
else
- job->req->sense_len = job->reply_len;
+ job->req->block_pc->sense_len = job->reply_len;
/* we assume all request payload was transferred, residual == 0 */
req->resid_len = 0;
@@ -124,9 +124,9 @@ static int bsg_create_job(struct device *dev, struct request *req)
job->req = req;
if (q->bsg_job_size)
job->dd_data = (void *)&job[1];
- job->request = req->cmd;
- job->request_len = req->cmd_len;
- job->reply = req->sense;
+ job->request = req->block_pc->cmd;
+ job->request_len = req->block_pc->cmd_len;
+ job->reply = req->block_pc->sense;
job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
* allocated */
if (req->bio) {
@@ -140,18 +140,13 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
struct sg_io_v4 *hdr, struct bsg_device *bd,
fmode_t has_write_perm)
{
- if (hdr->request_len > BLK_MAX_CDB) {
- rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
- if (!rq->cmd)
- return -ENOMEM;
- }
-
- if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request,
+ if (copy_from_user(rq->block_pc->cmd,
+ (void __user *)(unsigned long)hdr->request,
hdr->request_len))
return -EFAULT;
if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
- if (blk_verify_command(rq->cmd, has_write_perm))
+ if (blk_verify_command(rq->block_pc->cmd, has_write_perm))
return -EPERM;
} else if (!capable(CAP_SYS_RAWIO))
return -EPERM;
@@ -159,8 +154,6 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
/*
* fill in request structure
*/
- rq->cmd_len = hdr->request_len;
-
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
rq->timeout = q->sg_timeout;
@@ -236,7 +229,10 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
rq = blk_get_request(q, rw, GFP_KERNEL);
if (IS_ERR(rq))
return rq;
- blk_rq_set_block_pc(rq);
+
+ ret = blk_rq_set_block_pc(rq, hdr->request_len, sense, GFP_KERNEL);
+ if (ret)
+ goto out;
ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
if (ret)
@@ -280,13 +276,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
goto out;
}
- rq->sense = sense;
- rq->sense_len = 0;
-
return rq;
out:
- if (rq->cmd != rq->__cmd)
- kfree(rq->cmd);
blk_put_request(rq);
if (next_rq) {
blk_rq_unmap_user(next_rq->bio);
@@ -407,12 +398,12 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
hdr->info |= SG_INFO_CHECK;
hdr->response_len = 0;
- if (rq->sense_len && hdr->response) {
+ if (rq->block_pc->sense_len && hdr->response) {
int len = min_t(unsigned int, hdr->max_response_len,
- rq->sense_len);
+ rq->block_pc->sense_len);
ret = copy_to_user((void __user *)(unsigned long)hdr->response,
- rq->sense, len);
+ rq->block_pc->sense, len);
if (!ret)
hdr->response_len = len;
else
@@ -439,8 +430,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
ret = rq->errors;
blk_rq_unmap_user(bio);
- if (rq->cmd != rq->__cmd)
- kfree(rq->cmd);
blk_put_request(rq);
return ret;
@@ -227,16 +227,14 @@ EXPORT_SYMBOL(blk_verify_command);
static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
struct sg_io_hdr *hdr, fmode_t mode)
{
- if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
+ if (copy_from_user(rq->block_pc->cmd, hdr->cmdp, hdr->cmd_len))
return -EFAULT;
- if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
+ if (blk_verify_command(rq->block_pc->cmd, mode & FMODE_WRITE))
return -EPERM;
/*
* fill in request structure
*/
- rq->cmd_len = hdr->cmd_len;
-
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
rq->timeout = q->sg_timeout;
@@ -267,10 +265,11 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->resid = rq->resid_len;
hdr->sb_len_wr = 0;
- if (rq->sense_len && hdr->sbp) {
- int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
+ if (rq->block_pc->sense_len && hdr->sbp) {
+ int len = min((unsigned int) hdr->mx_sb_len,
+ rq->block_pc->sense_len);
- if (!copy_to_user(hdr->sbp, rq->sense, len))
+ if (!copy_to_user(hdr->sbp, rq->block_pc->sense, len))
hdr->sb_len_wr = len;
else
ret = -EFAULT;
@@ -291,7 +290,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
int writing = 0;
int at_head = 0;
struct request *rq;
- char sense[SCSI_SENSE_BUFFERSIZE];
struct bio *bio;
if (hdr->interface_id != 'S')
@@ -318,17 +316,14 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
if (IS_ERR(rq))
return PTR_ERR(rq);
- blk_rq_set_block_pc(rq);
- if (hdr->cmd_len > BLK_MAX_CDB) {
- rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
- if (!rq->cmd)
- goto out_put_request;
- }
+ ret = blk_rq_set_block_pc(rq, hdr->cmd_len, NULL, GFP_KERNEL);
+ if (ret)
+ goto out_put_request;
ret = -EFAULT;
if (blk_fill_sghdr_rq(q, rq, hdr, mode))
- goto out_free_cdb;
+ goto out_put_request;
ret = 0;
if (hdr->iovec_count) {
@@ -339,7 +334,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
hdr->dxferp, hdr->iovec_count,
0, &iov, &i);
if (ret < 0)
- goto out_free_cdb;
+ goto out_put_request;
/* SG_IO howto says that the shorter of the two wins */
iov_iter_truncate(&i, hdr->dxfer_len);
@@ -351,12 +346,9 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
GFP_KERNEL);
if (ret)
- goto out_free_cdb;
+ goto out_put_request;
bio = rq->bio;
- memset(sense, 0, sizeof(sense));
- rq->sense = sense;
- rq->sense_len = 0;
rq->retries = 0;
start_time = jiffies;
@@ -371,9 +363,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
ret = blk_complete_sghdr_rq(rq, hdr, bio);
-out_free_cdb:
- if (rq->cmd != rq->__cmd)
- kfree(rq->cmd);
out_put_request:
blk_put_request(rq);
return ret;
@@ -449,22 +438,23 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
err = PTR_ERR(rq);
goto error_free_buffer;
}
- blk_rq_set_block_pc(rq);
cmdlen = COMMAND_SIZE(opcode);
+ err = blk_rq_set_block_pc(rq, cmdlen, sense, GFP_KERNEL);
+ if (err)
+ goto error;
/*
* get command and data to send to device, if any
*/
err = -EFAULT;
- rq->cmd_len = cmdlen;
- if (copy_from_user(rq->cmd, sic->data, cmdlen))
+ if (copy_from_user(rq->block_pc->cmd, sic->data, cmdlen))
goto error;
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error;
- err = blk_verify_command(rq->cmd, mode & FMODE_WRITE);
+ err = blk_verify_command(rq->block_pc->cmd, mode & FMODE_WRITE);
if (err)
goto error;
@@ -500,18 +490,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
goto error;
}
- memset(sense, 0, sizeof(sense));
- rq->sense = sense;
- rq->sense_len = 0;
-
blk_execute_rq(q, disk, rq, 0);
err = rq->errors & 0xff; /* only 8 bit SCSI status */
if (err) {
- if (rq->sense_len && rq->sense) {
- bytes = (OMAX_SB_LEN > rq->sense_len) ?
- rq->sense_len : OMAX_SB_LEN;
- if (copy_to_user(sic->data, rq->sense, bytes))
+ if (rq->block_pc->sense_len) {
+ bytes = (OMAX_SB_LEN > rq->block_pc->sense_len) ?
+ rq->block_pc->sense_len : OMAX_SB_LEN;
+ if (copy_to_user(sic->data, rq->block_pc->sense, bytes))
err = -EFAULT;
}
} else {
@@ -539,14 +525,16 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, WRITE, __GFP_WAIT);
if (IS_ERR(rq))
return PTR_ERR(rq);
- blk_rq_set_block_pc(rq);
+ err = blk_rq_set_block_pc(rq, 6, NULL, GFP_KERNEL);
+ if (err)
+ goto out_put_request;
+
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
- rq->cmd[0] = cmd;
- rq->cmd[4] = data;
- rq->cmd_len = 6;
+ rq->block_pc->cmd[0] = cmd;
+ rq->block_pc->cmd[4] = data;
err = blk_execute_rq(q, bd_disk, rq, 0);
+out_put_request:
blk_put_request(rq);
-
return err;
}
@@ -1143,7 +1143,7 @@ static int atapi_drain_needed(struct request *rq)
if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_WRITE))
return 0;
- return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
+ return atapi_cmd_type(rq->block_pc->cmd[0]) == ATAPI_MISC;
}
static int ata_scsi_dev_config(struct scsi_device *sdev,
@@ -706,7 +706,11 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
WRITE : READ, __GFP_WAIT);
if (IS_ERR(rq))
return PTR_ERR(rq);
- blk_rq_set_block_pc(rq);
+
+ ret = blk_rq_set_block_pc(rq, COMMAND_SIZE(cgc->cmd[0]), NULL,
+ GFP_KERNEL);
+ if (ret)
+ goto out;
if (cgc->buflen) {
ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
@@ -715,8 +719,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
goto out;
}
- rq->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
- memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
+ memcpy(rq->block_pc->cmd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ;
if (cgc->quiet)
@@ -90,7 +90,8 @@ static int __virtblk_add_req(struct virtqueue *vq,
* inhdr with additional status information.
*/
if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
- sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len);
+ sg_init_one(&cmd, vbr->req->block_pc->cmd,
+ vbr->req->block_pc->cmd_len);
sgs[num_out++] = &cmd;
}
@@ -102,7 +103,8 @@ static int __virtblk_add_req(struct virtqueue *vq,
}
if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
- sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
+ sg_init_one(&sense, vbr->req->block_pc->sense,
+ SCSI_SENSE_BUFFERSIZE);
sgs[num_out + num_in++] = &sense;
sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
sgs[num_out + num_in++] = &inhdr;
@@ -122,7 +124,8 @@ static inline void virtblk_request_done(struct request *req)
if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
- req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
+ req->block_pc->sense_len =
+ virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
} else if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
req->errors = (error != 0);
@@ -2160,6 +2160,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
int lba, int nframes)
{
struct request_queue *q = cdi->disk->queue;
+ struct request_sense sense;
struct request *rq;
struct bio *bio;
unsigned int len;
@@ -2184,7 +2185,14 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
ret = PTR_ERR(rq);
break;
}
- blk_rq_set_block_pc(rq);
+
+ memset(&sense, 0, sizeof(sense));
+
+ ret = blk_rq_set_block_pc(rq, 10, (u8 *)&sense, GFP_KERNEL);
+ if (ret) {
+ blk_put_request(rq);
+ break;
+ }
ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
if (ret) {
@@ -2192,25 +2200,23 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
break;
}
- rq->cmd[0] = GPCMD_READ_CD;
- rq->cmd[1] = 1 << 2;
- rq->cmd[2] = (lba >> 24) & 0xff;
- rq->cmd[3] = (lba >> 16) & 0xff;
- rq->cmd[4] = (lba >> 8) & 0xff;
- rq->cmd[5] = lba & 0xff;
- rq->cmd[6] = (nr >> 16) & 0xff;
- rq->cmd[7] = (nr >> 8) & 0xff;
- rq->cmd[8] = nr & 0xff;
- rq->cmd[9] = 0xf8;
-
- rq->cmd_len = 12;
+ rq->block_pc->cmd[0] = GPCMD_READ_CD;
+ rq->block_pc->cmd[1] = 1 << 2;
+ rq->block_pc->cmd[2] = (lba >> 24) & 0xff;
+ rq->block_pc->cmd[3] = (lba >> 16) & 0xff;
+ rq->block_pc->cmd[4] = (lba >> 8) & 0xff;
+ rq->block_pc->cmd[5] = lba & 0xff;
+ rq->block_pc->cmd[6] = (nr >> 16) & 0xff;
+ rq->block_pc->cmd[7] = (nr >> 8) & 0xff;
+ rq->block_pc->cmd[8] = nr & 0xff;
+ rq->block_pc->cmd[9] = 0xf8;
+
rq->timeout = 60 * HZ;
bio = rq->bio;
if (blk_execute_rq(q, cdi->disk, rq, 0)) {
- struct request_sense *s = rq->sense;
ret = -EIO;
- cdi->last_sense = s->sense_key;
+ cdi->last_sense = sense.sense_key;
}
if (blk_rq_unmap_user(bio))
@@ -1069,6 +1069,7 @@ static void dm_end_request(struct request *clone, int error)
struct mapped_device *md = tio->md;
struct request *rq = tio->orig;
+#if 0
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
rq->errors = clone->errors;
rq->resid_len = clone->resid_len;
@@ -1081,6 +1082,7 @@ static void dm_end_request(struct request *clone, int error)
*/
rq->sense_len = clone->sense_len;
}
+#endif
free_rq_clone(clone);
blk_end_request_all(rq, error);
@@ -1773,9 +1775,11 @@ static int setup_clone(struct request *clone, struct request *rq,
if (r)
return r;
+#if 0
clone->cmd = rq->cmd;
clone->cmd_len = rq->cmd_len;
clone->sense = rq->sense;
+#endif
clone->end_io = end_clone_request;
clone->end_io_data = tio;
@@ -2321,8 +2321,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
SmpPassthroughReply_t *smprep;
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
- memcpy(req->sense, smprep, sizeof(*smprep));
- req->sense_len = sizeof(*smprep);
+ memcpy(req->block_pc->sense, smprep, sizeof(*smprep));
+ req->block_pc->sense_len = sizeof(*smprep);
req->resid_len = 0;
rsp->resid_len -= smprep->ResponseDataLength;
} else {
@@ -107,7 +107,7 @@ static int realloc_buffer(struct alua_dh_data *h, unsigned len)
}
static struct request *get_alua_req(struct scsi_device *sdev,
- void *buffer, unsigned buflen, int rw)
+ struct alua_dh_data *h, unsigned buflen, int rw)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
@@ -119,9 +119,16 @@ static struct request *get_alua_req(struct scsi_device *sdev,
"%s: blk_get_request failed\n", __func__);
return NULL;
}
- blk_rq_set_block_pc(rq);
- if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
+ memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ h->senselen = 0;
+
+ if (blk_rq_set_block_pc(rq, 16, h->sense, GFP_NOIO)) {
+ blk_put_request(rq);
+ return NULL;
+ }
+
+ if (buflen && blk_rq_map_kern(q, rq, h->buff, buflen, GFP_NOIO)) {
blk_put_request(rq);
sdev_printk(KERN_INFO, sdev,
"%s: blk_rq_map_kern failed\n", __func__);
@@ -145,27 +152,23 @@ static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
struct request *rq;
int err = SCSI_DH_RES_TEMP_UNAVAIL;
- rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
+ rq = get_alua_req(sdev, h, h->bufflen, READ);
if (!rq)
goto done;
/* Prepare the command. */
- rq->cmd[0] = INQUIRY;
- rq->cmd[1] = 1;
- rq->cmd[2] = 0x83;
- rq->cmd[4] = h->bufflen;
- rq->cmd_len = COMMAND_SIZE(INQUIRY);
-
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = h->senselen = 0;
+ rq->block_pc->cmd[0] = INQUIRY;
+ rq->block_pc->cmd[1] = 1;
+ rq->block_pc->cmd[2] = 0x83;
+ rq->block_pc->cmd[4] = h->bufflen;
+ rq->block_pc->cmd_len = COMMAND_SIZE(INQUIRY);
err = blk_execute_rq(rq->q, NULL, rq, 1);
if (err == -EIO) {
sdev_printk(KERN_INFO, sdev,
"%s: evpd inquiry failed with %x\n",
ALUA_DH_NAME, rq->errors);
- h->senselen = rq->sense_len;
+ h->senselen = rq->block_pc->sense_len;
err = SCSI_DH_IO;
}
blk_put_request(rq);
@@ -183,32 +186,28 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,
struct request *rq;
int err = SCSI_DH_RES_TEMP_UNAVAIL;
- rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
+ rq = get_alua_req(sdev, h, h->bufflen, READ);
if (!rq)
goto done;
/* Prepare the command. */
- rq->cmd[0] = MAINTENANCE_IN;
+ rq->block_pc->cmd[0] = MAINTENANCE_IN;
if (rtpg_ext_hdr_req)
- rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
+ rq->block_pc->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
else
- rq->cmd[1] = MI_REPORT_TARGET_PGS;
- rq->cmd[6] = (h->bufflen >> 24) & 0xff;
- rq->cmd[7] = (h->bufflen >> 16) & 0xff;
- rq->cmd[8] = (h->bufflen >> 8) & 0xff;
- rq->cmd[9] = h->bufflen & 0xff;
- rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
-
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = h->senselen = 0;
+ rq->block_pc->cmd[1] = MI_REPORT_TARGET_PGS;
+ rq->block_pc->cmd[6] = (h->bufflen >> 24) & 0xff;
+ rq->block_pc->cmd[7] = (h->bufflen >> 16) & 0xff;
+ rq->block_pc->cmd[8] = (h->bufflen >> 8) & 0xff;
+ rq->block_pc->cmd[9] = h->bufflen & 0xff;
+ rq->block_pc->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
err = blk_execute_rq(rq->q, NULL, rq, 1);
if (err == -EIO) {
sdev_printk(KERN_INFO, sdev,
"%s: rtpg failed with %x\n",
ALUA_DH_NAME, rq->errors);
- h->senselen = rq->sense_len;
+ h->senselen = rq->block_pc->sense_len;
err = SCSI_DH_IO;
}
blk_put_request(rq);
@@ -237,7 +236,7 @@ static void stpg_endio(struct request *req, int error)
goto done;
}
- if (req->sense_len > 0) {
+ if (req->block_pc->sense_len > 0) {
err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
&sense_hdr);
if (!err) {
@@ -293,22 +292,19 @@ static unsigned submit_stpg(struct alua_dh_data *h)
h->buff[6] = (h->group_id >> 8) & 0xff;
h->buff[7] = h->group_id & 0xff;
- rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
+ rq = get_alua_req(sdev, h, stpg_len, WRITE);
if (!rq)
return SCSI_DH_RES_TEMP_UNAVAIL;
/* Prepare the command. */
- rq->cmd[0] = MAINTENANCE_OUT;
- rq->cmd[1] = MO_SET_TARGET_PGS;
- rq->cmd[6] = (stpg_len >> 24) & 0xff;
- rq->cmd[7] = (stpg_len >> 16) & 0xff;
- rq->cmd[8] = (stpg_len >> 8) & 0xff;
- rq->cmd[9] = stpg_len & 0xff;
- rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
-
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = h->senselen = 0;
+ rq->block_pc->cmd[0] = MAINTENANCE_OUT;
+ rq->block_pc->cmd[1] = MO_SET_TARGET_PGS;
+ rq->block_pc->cmd[6] = (stpg_len >> 24) & 0xff;
+ rq->block_pc->cmd[7] = (stpg_len >> 16) & 0xff;
+ rq->block_pc->cmd[8] = (stpg_len >> 8) & 0xff;
+ rq->block_pc->cmd[9] = stpg_len & 0xff;
+ rq->block_pc->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
+
rq->end_io_data = h;
blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
@@ -267,8 +267,8 @@ out:
* Uses data and sense buffers in hardware handler context structure and
* assumes serial servicing of commands, both issuance and completion.
*/
-static struct request *get_req(struct scsi_device *sdev, int cmd,
- unsigned char *buffer)
+static struct request *get_req(struct scsi_device *sdev,
+ struct clariion_dh_data *csdev, int cmd)
{
struct request *rq;
int len = 0;
@@ -280,25 +280,31 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
return NULL;
}
- blk_rq_set_block_pc(rq);
- rq->cmd_len = COMMAND_SIZE(cmd);
- rq->cmd[0] = cmd;
+ memset(csdev->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ csdev->senselen = 0;
+
+ if (blk_rq_set_block_pc(rq, COMMAND_SIZE(cmd),
+ csdev->sense, GFP_NOIO)) {
+ blk_put_request(rq);
+ return NULL;
+ }
+ rq->block_pc->cmd[0] = cmd;
switch (cmd) {
case MODE_SELECT:
len = sizeof(short_trespass);
- rq->cmd[1] = 0x10;
- rq->cmd[4] = len;
+ rq->block_pc->cmd[1] = 0x10;
+ rq->block_pc->cmd[4] = len;
break;
case MODE_SELECT_10:
len = sizeof(long_trespass);
- rq->cmd[1] = 0x10;
- rq->cmd[8] = len;
+ rq->block_pc->cmd[1] = 0x10;
+ rq->block_pc->cmd[8] = len;
break;
case INQUIRY:
len = CLARIION_BUFFER_SIZE;
- rq->cmd[4] = len;
- memset(buffer, 0, len);
+ rq->block_pc->cmd[4] = len;
+ memset(csdev->buffer, 0, len);
break;
default:
BUG_ON(1);
@@ -310,7 +316,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
rq->timeout = CLARIION_TIMEOUT;
rq->retries = CLARIION_RETRIES;
- if (blk_rq_map_kern(rq->q, rq, buffer, len, GFP_NOIO)) {
+ if (blk_rq_map_kern(rq->q, rq, csdev->buffer, len, GFP_NOIO)) {
blk_put_request(rq);
return NULL;
}
@@ -321,20 +327,16 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
static int send_inquiry_cmd(struct scsi_device *sdev, int page,
struct clariion_dh_data *csdev)
{
- struct request *rq = get_req(sdev, INQUIRY, csdev->buffer);
+ struct request *rq = get_req(sdev, csdev, INQUIRY);
int err;
if (!rq)
return SCSI_DH_RES_TEMP_UNAVAIL;
- rq->sense = csdev->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = csdev->senselen = 0;
-
- rq->cmd[0] = INQUIRY;
+ rq->block_pc->cmd[0] = INQUIRY;
if (page != 0) {
- rq->cmd[1] = 1;
- rq->cmd[2] = page;
+ rq->block_pc->cmd[1] = 1;
+ rq->block_pc->cmd[2] = page;
}
err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
if (err == -EIO) {
@@ -342,7 +344,7 @@ static int send_inquiry_cmd(struct scsi_device *sdev, int page,
"%s: failed to send %s INQUIRY: %x\n",
CLARIION_NAME, page?"EVPD":"standard",
rq->errors);
- csdev->senselen = rq->sense_len;
+ csdev->senselen = rq->block_pc->sense_len;
err = SCSI_DH_IO;
}
@@ -376,17 +378,13 @@ static int send_trespass_cmd(struct scsi_device *sdev,
BUG_ON((len > CLARIION_BUFFER_SIZE));
memcpy(csdev->buffer, page22, len);
- rq = get_req(sdev, cmd, csdev->buffer);
+ rq = get_req(sdev, csdev, cmd);
if (!rq)
return SCSI_DH_RES_TEMP_UNAVAIL;
- rq->sense = csdev->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = csdev->senselen = 0;
-
err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
if (err == -EIO) {
- if (rq->sense_len) {
+ if (rq->block_pc->sense_len) {
err = trespass_endio(sdev, csdev->sense);
} else {
sdev_printk(KERN_INFO, sdev,
@@ -119,19 +119,21 @@ retry:
if (IS_ERR(req))
return SCSI_DH_RES_TEMP_UNAVAIL;
- blk_rq_set_block_pc(req);
+ memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+ ret = blk_rq_set_block_pc(req, 16, h->sense, GFP_NOIO);
+ if (ret)
+ goto out;
+
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
- req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
- req->cmd[0] = TEST_UNIT_READY;
+ req->block_pc->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
+ req->block_pc->cmd[0] = TEST_UNIT_READY;
req->timeout = HP_SW_TIMEOUT;
- req->sense = h->sense;
- memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
- req->sense_len = 0;
ret = blk_execute_rq(req->q, NULL, req, 1);
if (ret == -EIO) {
- if (req->sense_len > 0) {
+ if (req->block_pc->sense_len > 0) {
ret = tur_done(sdev, h->sense);
} else {
sdev_printk(KERN_WARNING, sdev,
@@ -152,8 +154,8 @@ retry:
ret = SCSI_DH_OK;
}
+out:
blk_put_request(req);
-
return ret;
}
@@ -212,7 +214,7 @@ static void start_stop_endio(struct request *req, int error)
goto done;
}
- if (req->sense_len > 0) {
+ if (req->block_pc->sense_len > 0) {
err = start_done(h->sdev, h->sense);
if (err == SCSI_DH_RETRY) {
err = SCSI_DH_IO;
@@ -249,16 +251,20 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
if (IS_ERR(req))
return SCSI_DH_RES_TEMP_UNAVAIL;
- blk_rq_set_block_pc(req);
+ memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+ if (blk_rq_set_block_pc(req, 16, h->sense, GFP_ATOMIC) < 0) {
+ blk_put_request(req);
+ return SCSI_DH_RES_TEMP_UNAVAIL;
+ }
+
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
- req->cmd_len = COMMAND_SIZE(START_STOP);
- req->cmd[0] = START_STOP;
- req->cmd[4] = 1; /* Start spin cycle */
+ req->block_pc->cmd_len = COMMAND_SIZE(START_STOP);
+ req->block_pc->cmd[0] = START_STOP;
+ req->block_pc->cmd[4] = 1; /* Start spin cycle */
req->timeout = HP_SW_TIMEOUT;
- req->sense = h->sense;
- memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
- req->sense_len = 0;
+
req->end_io_data = h;
blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
@@ -266,7 +266,7 @@ static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev)
}
static struct request *get_rdac_req(struct scsi_device *sdev,
- void *buffer, unsigned buflen, int rw)
+ struct rdac_dh_data *h, void *buffer, unsigned buflen, int rw)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
@@ -278,7 +278,12 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
"get_rdac_req: blk_get_request failed.\n");
return NULL;
}
- blk_rq_set_block_pc(rq);
+
+ memset(h->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ if (blk_rq_set_block_pc(rq, 16, h->sense, GFP_NOIO)) {
+ blk_put_request(rq);
+ return NULL;
+ }
if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
@@ -336,24 +341,20 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
}
/* get request for block layer packet command */
- rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE);
+ rq = get_rdac_req(sdev, h, &h->ctlr->mode_select, data_size, WRITE);
if (!rq)
return NULL;
/* Prepare the command. */
if (h->ctlr->use_ms10) {
- rq->cmd[0] = MODE_SELECT_10;
- rq->cmd[7] = data_size >> 8;
- rq->cmd[8] = data_size & 0xff;
+ rq->block_pc->cmd[0] = MODE_SELECT_10;
+ rq->block_pc->cmd[7] = data_size >> 8;
+ rq->block_pc->cmd[8] = data_size & 0xff;
} else {
- rq->cmd[0] = MODE_SELECT;
- rq->cmd[4] = data_size;
+ rq->block_pc->cmd[0] = MODE_SELECT;
+ rq->block_pc->cmd[4] = data_size;
}
- rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
-
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = 0;
+ rq->block_pc->cmd_len = COMMAND_SIZE(rq->block_pc->cmd[0]);
return rq;
}
@@ -409,20 +410,16 @@ static int submit_inquiry(struct scsi_device *sdev, int page_code,
struct request_queue *q = sdev->request_queue;
int err = SCSI_DH_RES_TEMP_UNAVAIL;
- rq = get_rdac_req(sdev, &h->inq, len, READ);
+ rq = get_rdac_req(sdev, h, &h->inq, len, READ);
if (!rq)
goto done;
/* Prepare the command. */
- rq->cmd[0] = INQUIRY;
- rq->cmd[1] = 1;
- rq->cmd[2] = page_code;
- rq->cmd[4] = len;
- rq->cmd_len = COMMAND_SIZE(INQUIRY);
-
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = 0;
+ rq->block_pc->cmd[0] = INQUIRY;
+ rq->block_pc->cmd[1] = 1;
+ rq->block_pc->cmd[2] = page_code;
+ rq->block_pc->cmd[4] = len;
+ rq->block_pc->cmd_len = COMMAND_SIZE(INQUIRY);
err = blk_execute_rq(q, NULL, rq, 1);
if (err == -EIO)
@@ -2094,8 +2094,8 @@ _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);
+ memcpy(req->block_pc->sense, mpi_reply, sizeof(*mpi_reply));
+ req->block_pc->sense_len = sizeof(*mpi_reply);
req->resid_len = 0;
rsp->resid_len -=
le16_to_cpu(mpi_reply->ResponseDataLength);
@@ -2054,8 +2054,8 @@ _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);
+ memcpy(req->block_pc->sense, mpi_reply, sizeof(*mpi_reply));
+ req->block_pc->sense_len = sizeof(*mpi_reply);
req->resid_len = 0;
rsp->resid_len -=
le16_to_cpu(mpi_reply->ResponseDataLength);
@@ -480,7 +480,7 @@ 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 = req->block_pc->sense_len;
if (or->out.req)
or->out.residual = or->out.req->resid_len;
if (or->in.req)
@@ -1563,16 +1563,8 @@ static struct request *_make_request(struct request_queue *q, bool has_write,
{
if (oii->bio)
return blk_make_request(q, oii->bio, flags);
- else {
- struct request *req;
-
- req = blk_get_request(q, has_write ? WRITE : READ, flags);
- if (IS_ERR(req))
- return req;
-
- blk_rq_set_block_pc(req);
- return req;
- }
+ else
+ return blk_get_request(q, has_write ? WRITE : READ, flags);
}
static int _init_blk_request(struct osd_request *or,
@@ -1590,13 +1582,22 @@ static int _init_blk_request(struct osd_request *or,
goto out;
}
+ /*
+ * XXX: allocating max size here to avoid having to reorder all
+ * the code below.
+ */
+ ret = blk_rq_set_block_pc(req, 255, req->block_pc->sense, flags);
+ if (ret) {
+ blk_put_request(req);
+ goto out;
+ }
+
or->request = req;
req->cmd_flags |= REQ_QUIET;
req->timeout = or->timeout;
req->retries = or->retries;
- req->sense = or->sense;
- req->sense_len = 0;
+ req->block_pc->sense_len = 0;
if (has_out) {
or->out.req = req;
@@ -1608,7 +1609,6 @@ static int _init_blk_request(struct osd_request *or,
ret = PTR_ERR(req);
goto out;
}
- blk_rq_set_block_pc(req);
or->in.req = or->request->next_rq = req;
}
} else if (has_in)
@@ -1695,8 +1695,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);
+ memcpy(or->request->block_pc->cmd, or->cdb.buff, _osd_req_cdb_len(or));
+ or->request->block_pc->cmd_len = _osd_req_cdb_len(or);
return 0;
}
@@ -367,7 +367,9 @@ 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);
+ err = blk_rq_set_block_pc(req, cmd_len, SRpnt->sense, GFP_KERNEL);
+ if (err)
+ goto free_req;
req->cmd_flags |= REQ_QUIET;
SRpnt->bio = NULL;
@@ -404,11 +406,7 @@ 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;
+ memcpy(req->block_pc->cmd, cmd, cmd_len);
req->timeout = timeout;
req->retries = retries;
req->end_io_data = SRpnt;
@@ -909,7 +909,7 @@ qla2x00_process_loopback(struct fc_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 *)bsg_job->req->block_pc->sense) +
sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, response, sizeof(response));
fw_sts_ptr += sizeof(response);
@@ -1418,7 +1418,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*)bsg_job->req->block_pc->sense) +
+ sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
else {
@@ -1432,7 +1433,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
pkt)->error_subcode_2));
res = DID_ERROR << 16;
bsg_job->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*)bsg_job->req->block_pc->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,
@@ -2242,7 +2242,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 *)bsg_job->req->block_pc->sense) +
sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, (uint8_t *)&fstatus,
@@ -1968,16 +1968,18 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
if (IS_ERR(req))
return;
- 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;
+ if (blk_rq_set_block_pc(req, COMMAND_SIZE(ALLOW_MEDIUM_REMOVAL),
+ NULL, GFP_KERNEL) < 0) {
+ blk_put_request(req);
+ return;
+ }
- req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+ req->block_pc->cmd[0] = ALLOW_MEDIUM_REMOVAL;
+ req->block_pc->cmd[1] = 0;
+ req->block_pc->cmd[2] = 0;
+ req->block_pc->cmd[3] = 0;
+ req->block_pc->cmd[4] = SCSI_REMOVAL_PREVENT;
+ req->block_pc->cmd[5] = 0;
req->cmd_flags |= REQ_QUIET;
req->timeout = 10 * HZ;
@@ -2332,8 +2334,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
blk_rq_init(NULL, &req);
scmd->request = &req;
- scmd->cmnd = req.cmd;
-
scmd->scsi_done = scsi_reset_provider_done_command;
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
@@ -224,16 +224,15 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
if (IS_ERR(req))
return ret;
- blk_rq_set_block_pc(req);
+
+ if (blk_rq_set_block_pc(req, COMMAND_SIZE(cmd[0]), sense, GFP_KERNEL))
+ goto out;
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
buffer, bufflen, __GFP_WAIT))
goto out;
- req->cmd_len = COMMAND_SIZE(cmd[0]);
- memcpy(req->cmd, cmd, req->cmd_len);
- req->sense = sense;
- req->sense_len = 0;
+ memcpy(req->block_pc->cmd, cmd, req->block_pc->cmd_len);
req->retries = retries;
req->timeout = timeout;
req->cmd_flags |= flags | REQ_QUIET | REQ_PREEMPT;
@@ -835,7 +834,7 @@ 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 && req->block_pc->sense) {
/*
* SG_IO wants current and deferred errors
*/
@@ -843,8 +842,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (len > SCSI_SENSE_BUFFERSIZE)
len = SCSI_SENSE_BUFFERSIZE;
- memcpy(req->sense, cmd->sense_buffer, len);
- req->sense_len = len;
+ memcpy(req->block_pc->sense, cmd->sense_buffer, len);
+ req->block_pc->sense_len = len;
}
if (!sense_deferred)
error = __scsi_error_from_host_byte(cmd, result);
@@ -1208,7 +1207,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
cmd->tag = req->tag;
cmd->request = req;
- cmd->cmnd = req->cmd;
cmd->prot_op = SCSI_PROT_NORMAL;
return cmd;
@@ -1234,7 +1232,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 = req->block_pc->cmd_len;
+ cmd->cmnd = req->block_pc->cmd;
cmd->transfersize = blk_rq_bytes(req);
cmd->allowed = req->retries;
return BLKPREP_OK;
@@ -1255,7 +1254,7 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
return ret;
}
- memset(cmd->cmnd, 0, BLK_MAX_CDB);
+ cmd->cmnd = cmd->__cmnd;
return scsi_cmd_to_driver(cmd)->init_command(cmd);
}
@@ -1911,7 +1910,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);
@@ -3593,9 +3593,9 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
if (err < 0)
/* we're only returning the result field in the reply */
- job->req->sense_len = sizeof(uint32_t);
+ job->req->block_pc->sense_len = sizeof(uint32_t);
else
- job->req->sense_len = job->reply_len;
+ job->req->block_pc->sense_len = job->reply_len;
/* we assume all request payload was transferred, residual == 0 */
req->resid_len = 0;
@@ -3725,9 +3725,9 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
if (i->f->dd_bsg_size)
job->dd_data = (void *)&job[1];
spin_lock_init(&job->job_lock);
- job->request = (struct fc_bsg_request *)req->cmd;
- job->request_len = req->cmd_len;
- job->reply = req->sense;
+ job->request = (struct fc_bsg_request *)req->block_pc->cmd;
+ job->request_len = req->block_pc->cmd_len;
+ job->reply = req->block_pc->sense;
job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
* allocated */
if (req->bio) {
@@ -126,9 +126,6 @@ static DEFINE_IDA(sd_index_ida);
* object after last put) */
static DEFINE_MUTEX(sd_ref_mutex);
-static struct kmem_cache *sd_cdb_cache;
-static mempool_t *sd_cdb_pool;
-
static const char *sd_cache_types[] = {
"write through", "none", "write back",
"write back, no read (daft)"
@@ -1016,13 +1013,6 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
protect = 0;
if (protect && sdkp->protection_type == SD_DIF_TYPE2_PROTECTION) {
- SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
-
- if (unlikely(SCpnt->cmnd == NULL)) {
- ret = BLKPREP_DEFER;
- goto out;
- }
-
SCpnt->cmd_len = SD_EXT_CDB_SIZE;
memset(SCpnt->cmnd, 0, SCpnt->cmd_len);
SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD;
@@ -1138,12 +1128,6 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
if (rq->cmd_flags & REQ_DISCARD)
__free_page(rq->completion_data);
-
- if (SCpnt->cmnd != rq->cmd) {
- mempool_free(SCpnt->cmnd, sd_cdb_pool);
- SCpnt->cmnd = NULL;
- SCpnt->cmd_len = 0;
- }
}
/**
@@ -3221,38 +3205,17 @@ static int __init init_sd(void)
err = class_register(&sd_disk_class);
if (err)
- goto err_out;
-
- sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE,
- 0, 0, NULL);
- if (!sd_cdb_cache) {
- printk(KERN_ERR "sd: can't init extended cdb cache\n");
- err = -ENOMEM;
- goto err_out_class;
- }
-
- sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache);
- if (!sd_cdb_pool) {
- printk(KERN_ERR "sd: can't init extended cdb pool\n");
- err = -ENOMEM;
- goto err_out_cache;
- }
+ goto out_unregister_blkdev;
err = scsi_register_driver(&sd_template.gendrv);
if (err)
- goto err_out_driver;
+ goto out_unregister_class;
return 0;
-err_out_driver:
- mempool_destroy(sd_cdb_pool);
-
-err_out_cache:
- kmem_cache_destroy(sd_cdb_cache);
-
-err_out_class:
+out_unregister_class:
class_unregister(&sd_disk_class);
-err_out:
+out_unregister_blkdev:
for (i = 0; i < SD_MAJORS; i++)
unregister_blkdev(sd_major(i), "sd");
return err;
@@ -3270,8 +3233,6 @@ static void __exit exit_sd(void)
SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
scsi_unregister_driver(&sd_template.gendrv);
- mempool_destroy(sd_cdb_pool);
- kmem_cache_destroy(sd_cdb_cache);
class_unregister(&sd_disk_class);
@@ -1297,7 +1297,7 @@ 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 = rq->block_pc->sense;
result = rq->errors;
resid = rq->resid_len;
@@ -1342,8 +1342,6 @@ 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);
__blk_put_request(rq->q, rq);
write_lock_irqsave(&sfp->rq_list_lock, iflags);
@@ -1701,16 +1699,16 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
return PTR_ERR(rq);
}
- blk_rq_set_block_pc(rq);
+ res = blk_rq_set_block_pc(rq, hp->cmd_len, srp->sense_b, GFP_KERNEL);
+ if (res) {
+ blk_put_request(rq);
+ return res;
+ }
- if (hp->cmd_len > BLK_MAX_CDB)
- rq->cmd = long_cmdp;
- memcpy(rq->cmd, cmd, hp->cmd_len);
- rq->cmd_len = hp->cmd_len;
+ memcpy(rq->block_pc->cmd, cmd, 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))
@@ -1785,11 +1783,8 @@ sg_finish_rem_req(Sg_request *srp)
if (srp->bio)
ret = blk_rq_unmap_user(srp->bio);
- if (srp->rq) {
- if (srp->rq->cmd != srp->rq->__cmd)
- kfree(srp->rq->cmd);
+ if (srp->rq)
blk_put_request(srp->rq);
- }
if (srp->res_used)
sg_unlink_reserve(sfp, srp);
@@ -502,7 +502,10 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
if (IS_ERR(req))
return DRIVER_ERROR << 24;
- blk_rq_set_block_pc(req);
+ err = blk_rq_set_block_pc(req, COMMAND_SIZE(cmd[0]), SRpnt->sense,
+ GFP_KERNEL);
+ if (err)
+ goto out_put_request;
req->cmd_flags |= REQ_QUIET;
mdata->null_mapped = 1;
@@ -510,24 +513,22 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
if (bufflen) {
err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
GFP_KERNEL);
- if (err) {
- blk_put_request(req);
- return DRIVER_ERROR << 24;
- }
+ if (err)
+ goto out_put_request;
}
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;
+ memcpy(req->block_pc->cmd, cmd, req->block_pc->cmd_len);
req->timeout = timeout;
req->retries = retries;
req->end_io_data = SRpnt;
blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
return 0;
+
+out_put_request:
+ blk_put_request(req);
+ return DRIVER_ERROR << 24;
}
/* Do the scsi command. Waits until command performed if do_wait is true.
@@ -1064,8 +1064,6 @@ pscsi_execute_cmd(struct se_cmd *cmd)
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto fail;
}
-
- blk_rq_set_block_pc(req);
} else {
BUG_ON(!cmd->data_length);
@@ -1082,12 +1080,16 @@ pscsi_execute_cmd(struct se_cmd *cmd)
}
}
+ if (blk_rq_set_block_pc(req, scsi_command_size(pt->pscsi_cdb),
+ &pt->pscsi_sense[0], GFP_KERNEL)) {
+ blk_put_request(req);
+ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ goto fail;
+ }
+
req->end_io = pscsi_req_done;
req->end_io_data = cmd;
- req->cmd_len = scsi_command_size(pt->pscsi_cdb);
- req->cmd = &pt->pscsi_cdb[0];
- req->sense = &pt->pscsi_sense[0];
- req->sense_len = 0;
+ memcpy(req->block_pc->cmd, &pt->pscsi_cdb[0], req->block_pc->cmd_len);
if (pdv->pdv_sd->type == TYPE_DISK)
req->timeout = PS_TIMEOUT_DISK;
else
@@ -80,6 +80,16 @@ enum rq_cmd_type_bits {
#define BLK_MAX_CDB 16
/*
+ * when request is used as a packet command carrier
+ */
+struct block_pc_request {
+ unsigned short cmd_len;
+ unsigned int sense_len;
+ void *sense;
+ unsigned char cmd[];
+};
+
+/*
* Try to put the fields that are referenced together in the same cacheline.
*
* If you modify this structure, make sure to update blk_rq_init() and
@@ -172,23 +182,19 @@ struct request {
int tag;
int errors;
- /*
- * when request is used as a packet command carrier
- */
- unsigned char __cmd[BLK_MAX_CDB];
- unsigned char *cmd;
- unsigned short cmd_len;
-
unsigned int extra_len; /* length of alignment and padding */
- unsigned int sense_len;
unsigned int resid_len; /* residual count */
- void *sense;
unsigned long deadline;
struct list_head timeout_list;
unsigned int timeout;
int retries;
+ union {
+ struct block_pc_request *block_pc;
+ void *drv_private;
+ };
+
/*
* completion callback.
*/
@@ -769,7 +775,8 @@ extern void __blk_put_request(struct request_queue *, struct request *);
extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
extern struct request *blk_make_request(struct request_queue *, struct bio *,
gfp_t);
-extern void blk_rq_set_block_pc(struct request *);
+int blk_rq_set_block_pc(struct request *rq, unsigned short cmd_len,
+ u8 *sense, gfp_t gfp);
extern void blk_requeue_request(struct request_queue *, struct request *);
extern void blk_add_request_payload(struct request *rq, struct page *page,
unsigned int len);
@@ -105,7 +105,9 @@ struct compat_blk_user_trace_setup {
static inline int blk_cmd_buf_len(struct request *rq)
{
- return (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? rq->cmd_len * 3 : 1;
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
+ return rq->block_pc->cmd_len * 3;
+ return 1;
}
extern void blk_dump_cmd(char *buf, struct request *rq);
@@ -92,7 +92,7 @@ struct scsi_cmnd {
/* These elements define the operation we are about to perform */
unsigned char *cmnd;
-
+ unsigned char __cmnd[32];
/* These elements define the operation we ultimately want to perform */
struct scsi_data_buffer sdb;
@@ -720,7 +720,9 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
what |= BLK_TC_ACT(BLK_TC_PC);
__blk_add_trace(bt, 0, nr_bytes, rq->cmd_flags,
- what, rq->errors, rq->cmd_len, rq->cmd);
+ what, rq->errors,
+ rq->block_pc->cmd_len,
+ rq->block_pc->cmd);
} else {
what |= BLK_TC_ACT(BLK_TC_FS);
__blk_add_trace(bt, blk_rq_pos(rq), nr_bytes,
@@ -1762,14 +1764,17 @@ void blk_trace_remove_sysfs(struct device *dev)
void blk_dump_cmd(char *buf, struct request *rq)
{
int i, end;
- int len = rq->cmd_len;
- unsigned char *cmd = rq->cmd;
+ int len;
+ unsigned char *cmd;
if (rq->cmd_type != REQ_TYPE_BLOCK_PC) {
buf[0] = '\0';
return;
}
+ len = rq->block_pc->cmd_len;
+ cmd = rq->block_pc->cmd;
+
for (end = len - 1; end >= 0; end--)
if (cmd[end])
break;