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>
This commit is contained in:
Christoph Hellwig 2017-01-27 09:46:29 +01:00 коммит произвёл Jens Axboe
Родитель 8ae94eb65b
Коммит 82ed4db499
49 изменённых файлов: 457 добавлений и 409 удалений

Просмотреть файл

@ -132,8 +132,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
rq->__sector = (sector_t) -1; rq->__sector = (sector_t) -1;
INIT_HLIST_NODE(&rq->hash); INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node); RB_CLEAR_NODE(&rq->rb_node);
rq->cmd = rq->__cmd;
rq->cmd_len = BLK_MAX_CDB;
rq->tag = -1; rq->tag = -1;
rq->internal_tag = -1; rq->internal_tag = -1;
rq->start_time = jiffies; rq->start_time = jiffies;
@ -160,8 +158,6 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
void blk_dump_rq_flags(struct request *rq, char *msg) void blk_dump_rq_flags(struct request *rq, char *msg)
{ {
int bit;
printk(KERN_INFO "%s: dev %s: type=%x, flags=%llx\n", msg, printk(KERN_INFO "%s: dev %s: type=%x, flags=%llx\n", msg,
rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
(unsigned long long) rq->cmd_flags); (unsigned long long) rq->cmd_flags);
@ -171,13 +167,6 @@ void blk_dump_rq_flags(struct request *rq, char *msg)
blk_rq_sectors(rq), blk_rq_cur_sectors(rq)); blk_rq_sectors(rq), blk_rq_cur_sectors(rq));
printk(KERN_INFO " bio %p, biotail %p, len %u\n", printk(KERN_INFO " bio %p, biotail %p, len %u\n",
rq->bio, rq->biotail, blk_rq_bytes(rq)); rq->bio, rq->biotail, blk_rq_bytes(rq));
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("\n");
}
} }
EXPORT_SYMBOL(blk_dump_rq_flags); EXPORT_SYMBOL(blk_dump_rq_flags);
@ -1315,18 +1304,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
} }
EXPORT_SYMBOL(blk_get_request); EXPORT_SYMBOL(blk_get_request);
/**
* blk_rq_set_block_pc - initialize a request to type BLOCK_PC
* @rq: request to be initialized
*
*/
void blk_rq_set_block_pc(struct request *rq)
{
rq->cmd_type = REQ_TYPE_BLOCK_PC;
memset(rq->__cmd, 0, sizeof(rq->__cmd));
}
EXPORT_SYMBOL(blk_rq_set_block_pc);
/** /**
* blk_requeue_request - put a request back on queue * blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted * @q: request queue where request should be inserted
@ -2459,14 +2436,6 @@ void blk_start_request(struct request *req)
wbt_issue(req->q->rq_wb, &req->issue_stat); wbt_issue(req->q->rq_wb, &req->issue_stat);
} }
/*
* We are now handing the request to the hardware, initialize
* resid_len to full count and add the timeout handler.
*/
req->resid_len = blk_rq_bytes(req);
if (unlikely(blk_bidi_rq(req)))
req->next_rq->resid_len = blk_rq_bytes(req->next_rq);
BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags)); BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
blk_add_timer(req); blk_add_timer(req);
} }

Просмотреть файл

@ -11,11 +11,6 @@
#include "blk.h" #include "blk.h"
#include "blk-mq-sched.h" #include "blk-mq-sched.h"
/*
* for max sense size
*/
#include <scsi/scsi_cmnd.h>
/** /**
* blk_end_sync_rq - executes a completion event on a request * blk_end_sync_rq - executes a completion event on a request
* @rq: request to complete * @rq: request to complete
@ -101,16 +96,9 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
struct request *rq, int at_head) struct request *rq, int at_head)
{ {
DECLARE_COMPLETION_ONSTACK(wait); DECLARE_COMPLETION_ONSTACK(wait);
char sense[SCSI_SENSE_BUFFERSIZE];
int err = 0; int err = 0;
unsigned long hang_check; unsigned long hang_check;
if (!rq->sense) {
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
}
rq->end_io_data = &wait; rq->end_io_data = &wait;
blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq); blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
@ -124,11 +112,6 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
if (rq->errors) if (rq->errors)
err = -EIO; err = -EIO;
if (rq->sense == sense) {
rq->sense = NULL;
rq->sense_len = 0;
}
return err; return err;
} }
EXPORT_SYMBOL(blk_execute_rq); EXPORT_SYMBOL(blk_execute_rq);

Просмотреть файл

@ -199,13 +199,7 @@ void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
rq->special = NULL; rq->special = NULL;
/* tag was already set */ /* tag was already set */
rq->errors = 0; rq->errors = 0;
rq->cmd = rq->__cmd;
rq->extra_len = 0; rq->extra_len = 0;
rq->sense_len = 0;
rq->resid_len = 0;
rq->sense = NULL;
INIT_LIST_HEAD(&rq->timeout_list); INIT_LIST_HEAD(&rq->timeout_list);
rq->timeout = 0; rq->timeout = 0;
@ -487,10 +481,6 @@ void blk_mq_start_request(struct request *rq)
trace_block_rq_issue(q, rq); trace_block_rq_issue(q, rq);
rq->resid_len = blk_rq_bytes(rq);
if (unlikely(blk_bidi_rq(rq)))
rq->next_rq->resid_len = blk_rq_bytes(rq->next_rq);
if (test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) { if (test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) {
blk_stat_set_issue_time(&rq->issue_stat); blk_stat_set_issue_time(&rq->issue_stat);
rq->rq_flags |= RQF_STATS; rq->rq_flags |= RQF_STATS;

Просмотреть файл

@ -71,22 +71,24 @@ void bsg_job_done(struct bsg_job *job, int result,
{ {
struct request *req = job->req; struct request *req = job->req;
struct request *rsp = req->next_rq; struct request *rsp = req->next_rq;
struct scsi_request *rq = scsi_req(req);
int err; int err;
err = job->req->errors = result; err = job->req->errors = result;
if (err < 0) if (err < 0)
/* we're only returning the result field in the reply */ /* we're only returning the result field in the reply */
job->req->sense_len = sizeof(u32); rq->sense_len = sizeof(u32);
else else
job->req->sense_len = job->reply_len; rq->sense_len = job->reply_len;
/* we assume all request payload was transferred, residual == 0 */ /* we assume all request payload was transferred, residual == 0 */
req->resid_len = 0; rq->resid_len = 0;
if (rsp) { if (rsp) {
WARN_ON(reply_payload_rcv_len > rsp->resid_len); WARN_ON(reply_payload_rcv_len > scsi_req(rsp)->resid_len);
/* set reply (bidi) residual */ /* set reply (bidi) residual */
rsp->resid_len -= min(reply_payload_rcv_len, rsp->resid_len); scsi_req(rsp)->resid_len -=
min(reply_payload_rcv_len, scsi_req(rsp)->resid_len);
} }
blk_complete_request(req); blk_complete_request(req);
} }
@ -113,6 +115,7 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
if (!buf->sg_list) if (!buf->sg_list)
return -ENOMEM; return -ENOMEM;
sg_init_table(buf->sg_list, req->nr_phys_segments); sg_init_table(buf->sg_list, req->nr_phys_segments);
scsi_req(req)->resid_len = blk_rq_bytes(req);
buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list); buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
buf->payload_len = blk_rq_bytes(req); buf->payload_len = blk_rq_bytes(req);
return 0; return 0;
@ -127,6 +130,7 @@ static int bsg_create_job(struct device *dev, struct request *req)
{ {
struct request *rsp = req->next_rq; struct request *rsp = req->next_rq;
struct request_queue *q = req->q; struct request_queue *q = req->q;
struct scsi_request *rq = scsi_req(req);
struct bsg_job *job; struct bsg_job *job;
int ret; int ret;
@ -140,9 +144,9 @@ static int bsg_create_job(struct device *dev, struct request *req)
job->req = req; job->req = req;
if (q->bsg_job_size) if (q->bsg_job_size)
job->dd_data = (void *)&job[1]; job->dd_data = (void *)&job[1];
job->request = req->cmd; job->request = rq->cmd;
job->request_len = req->cmd_len; job->request_len = rq->cmd_len;
job->reply = req->sense; job->reply = rq->sense;
job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
* allocated */ * allocated */
if (req->bio) { if (req->bio) {
@ -228,9 +232,15 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
struct request_queue *q; struct request_queue *q;
int ret; int ret;
q = blk_init_queue(bsg_request_fn, NULL); q = blk_alloc_queue(GFP_KERNEL);
if (!q) if (!q)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
q->cmd_size = sizeof(struct scsi_request);
q->request_fn = bsg_request_fn;
ret = blk_init_allocated_queue(q);
if (ret)
goto out_cleanup_queue;
q->queuedata = dev; q->queuedata = dev;
q->bsg_job_size = dd_job_size; q->bsg_job_size = dd_job_size;
@ -243,10 +253,12 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
if (ret) { if (ret) {
printk(KERN_ERR "%s: bsg interface failed to " printk(KERN_ERR "%s: bsg interface failed to "
"initialize - register queue\n", dev->kobj.name); "initialize - register queue\n", dev->kobj.name);
blk_cleanup_queue(q); goto out_cleanup_queue;
return ERR_PTR(ret);
} }
return q; return q;
out_cleanup_queue:
blk_cleanup_queue(q);
return ERR_PTR(ret);
} }
EXPORT_SYMBOL_GPL(bsg_setup_queue); EXPORT_SYMBOL_GPL(bsg_setup_queue);

Просмотреть файл

@ -85,7 +85,6 @@ struct bsg_command {
struct bio *bidi_bio; struct bio *bidi_bio;
int err; int err;
struct sg_io_v4 hdr; struct sg_io_v4 hdr;
char sense[SCSI_SENSE_BUFFERSIZE];
}; };
static void bsg_free_command(struct bsg_command *bc) static void bsg_free_command(struct bsg_command *bc)
@ -140,18 +139,20 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
struct sg_io_v4 *hdr, struct bsg_device *bd, struct sg_io_v4 *hdr, struct bsg_device *bd,
fmode_t has_write_perm) fmode_t has_write_perm)
{ {
struct scsi_request *req = scsi_req(rq);
if (hdr->request_len > BLK_MAX_CDB) { if (hdr->request_len > BLK_MAX_CDB) {
rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); req->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
if (!rq->cmd) if (!req->cmd)
return -ENOMEM; return -ENOMEM;
} }
if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request, if (copy_from_user(req->cmd, (void __user *)(unsigned long)hdr->request,
hdr->request_len)) hdr->request_len))
return -EFAULT; return -EFAULT;
if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
if (blk_verify_command(rq->cmd, has_write_perm)) if (blk_verify_command(req->cmd, has_write_perm))
return -EPERM; return -EPERM;
} else if (!capable(CAP_SYS_RAWIO)) } else if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
@ -159,7 +160,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
/* /*
* fill in request structure * fill in request structure
*/ */
rq->cmd_len = hdr->request_len; req->cmd_len = hdr->request_len;
rq->timeout = msecs_to_jiffies(hdr->timeout); rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout) if (!rq->timeout)
@ -205,8 +206,7 @@ bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *rw)
* map sg_io_v4 to a request. * map sg_io_v4 to a request.
*/ */
static struct request * static struct request *
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
u8 *sense)
{ {
struct request_queue *q = bd->queue; struct request_queue *q = bd->queue;
struct request *rq, *next_rq = NULL; struct request *rq, *next_rq = NULL;
@ -236,7 +236,7 @@ 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); rq = blk_get_request(q, rw, GFP_KERNEL);
if (IS_ERR(rq)) if (IS_ERR(rq))
return rq; return rq;
blk_rq_set_block_pc(rq); scsi_req_init(rq);
ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm); ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
if (ret) if (ret)
@ -280,13 +280,9 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
goto out; goto out;
} }
rq->sense = sense;
rq->sense_len = 0;
return rq; return rq;
out: out:
if (rq->cmd != rq->__cmd) scsi_req_free_cmd(scsi_req(rq));
kfree(rq->cmd);
blk_put_request(rq); blk_put_request(rq);
if (next_rq) { if (next_rq) {
blk_rq_unmap_user(next_rq->bio); blk_rq_unmap_user(next_rq->bio);
@ -393,6 +389,7 @@ static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd)
static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
struct bio *bio, struct bio *bidi_bio) struct bio *bio, struct bio *bidi_bio)
{ {
struct scsi_request *req = scsi_req(rq);
int ret = 0; int ret = 0;
dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors); dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
@ -407,12 +404,12 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
hdr->info |= SG_INFO_CHECK; hdr->info |= SG_INFO_CHECK;
hdr->response_len = 0; hdr->response_len = 0;
if (rq->sense_len && hdr->response) { if (req->sense_len && hdr->response) {
int len = min_t(unsigned int, hdr->max_response_len, int len = min_t(unsigned int, hdr->max_response_len,
rq->sense_len); req->sense_len);
ret = copy_to_user((void __user *)(unsigned long)hdr->response, ret = copy_to_user((void __user *)(unsigned long)hdr->response,
rq->sense, len); req->sense, len);
if (!ret) if (!ret)
hdr->response_len = len; hdr->response_len = len;
else else
@ -420,14 +417,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
} }
if (rq->next_rq) { if (rq->next_rq) {
hdr->dout_resid = rq->resid_len; hdr->dout_resid = req->resid_len;
hdr->din_resid = rq->next_rq->resid_len; hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
blk_rq_unmap_user(bidi_bio); blk_rq_unmap_user(bidi_bio);
blk_put_request(rq->next_rq); blk_put_request(rq->next_rq);
} else if (rq_data_dir(rq) == READ) } else if (rq_data_dir(rq) == READ)
hdr->din_resid = rq->resid_len; hdr->din_resid = req->resid_len;
else else
hdr->dout_resid = rq->resid_len; hdr->dout_resid = req->resid_len;
/* /*
* If the request generated a negative error number, return it * If the request generated a negative error number, return it
@ -439,8 +436,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
ret = rq->errors; ret = rq->errors;
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
if (rq->cmd != rq->__cmd) scsi_req_free_cmd(req);
kfree(rq->cmd);
blk_put_request(rq); blk_put_request(rq);
return ret; return ret;
@ -625,7 +621,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
/* /*
* get a request, fill in the blanks, and add to request queue * get a request, fill in the blanks, and add to request queue
*/ */
rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense); rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm);
if (IS_ERR(rq)) { if (IS_ERR(rq)) {
ret = PTR_ERR(rq); ret = PTR_ERR(rq);
rq = NULL; rq = NULL;
@ -911,12 +907,11 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct bio *bio, *bidi_bio = NULL; struct bio *bio, *bidi_bio = NULL;
struct sg_io_v4 hdr; struct sg_io_v4 hdr;
int at_head; int at_head;
u8 sense[SCSI_SENSE_BUFFERSIZE];
if (copy_from_user(&hdr, uarg, sizeof(hdr))) if (copy_from_user(&hdr, uarg, sizeof(hdr)))
return -EFAULT; return -EFAULT;
rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense); rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);

Просмотреть файл

@ -230,15 +230,17 @@ EXPORT_SYMBOL(blk_verify_command);
static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
struct sg_io_hdr *hdr, fmode_t mode) struct sg_io_hdr *hdr, fmode_t mode)
{ {
if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) struct scsi_request *req = scsi_req(rq);
if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
return -EFAULT; return -EFAULT;
if (blk_verify_command(rq->cmd, mode & FMODE_WRITE)) if (blk_verify_command(req->cmd, mode & FMODE_WRITE))
return -EPERM; return -EPERM;
/* /*
* fill in request structure * fill in request structure
*/ */
rq->cmd_len = hdr->cmd_len; req->cmd_len = hdr->cmd_len;
rq->timeout = msecs_to_jiffies(hdr->timeout); rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout) if (!rq->timeout)
@ -254,6 +256,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
struct bio *bio) struct bio *bio)
{ {
struct scsi_request *req = scsi_req(rq);
int r, ret = 0; int r, ret = 0;
/* /*
@ -267,13 +270,13 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->info = 0; hdr->info = 0;
if (hdr->masked_status || hdr->host_status || hdr->driver_status) if (hdr->masked_status || hdr->host_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK; hdr->info |= SG_INFO_CHECK;
hdr->resid = rq->resid_len; hdr->resid = req->resid_len;
hdr->sb_len_wr = 0; hdr->sb_len_wr = 0;
if (rq->sense_len && hdr->sbp) { if (req->sense_len && hdr->sbp) {
int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len); int len = min((unsigned int) hdr->mx_sb_len, req->sense_len);
if (!copy_to_user(hdr->sbp, rq->sense, len)) if (!copy_to_user(hdr->sbp, req->sense, len))
hdr->sb_len_wr = len; hdr->sb_len_wr = len;
else else
ret = -EFAULT; ret = -EFAULT;
@ -294,7 +297,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
int writing = 0; int writing = 0;
int at_head = 0; int at_head = 0;
struct request *rq; struct request *rq;
char sense[SCSI_SENSE_BUFFERSIZE]; struct scsi_request *req;
struct bio *bio; struct bio *bio;
if (hdr->interface_id != 'S') if (hdr->interface_id != 'S')
@ -321,11 +324,12 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
blk_rq_set_block_pc(rq); req = scsi_req(rq);
scsi_req_init(rq);
if (hdr->cmd_len > BLK_MAX_CDB) { if (hdr->cmd_len > BLK_MAX_CDB) {
rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
if (!rq->cmd) if (!req->cmd)
goto out_put_request; goto out_put_request;
} }
@ -357,9 +361,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
goto out_free_cdb; goto out_free_cdb;
bio = rq->bio; bio = rq->bio;
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
rq->retries = 0; rq->retries = 0;
start_time = jiffies; start_time = jiffies;
@ -375,8 +376,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
ret = blk_complete_sghdr_rq(rq, hdr, bio); ret = blk_complete_sghdr_rq(rq, hdr, bio);
out_free_cdb: out_free_cdb:
if (rq->cmd != rq->__cmd) scsi_req_free_cmd(req);
kfree(rq->cmd);
out_put_request: out_put_request:
blk_put_request(rq); blk_put_request(rq);
return ret; return ret;
@ -420,9 +420,10 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
struct scsi_ioctl_command __user *sic) struct scsi_ioctl_command __user *sic)
{ {
struct request *rq; struct request *rq;
struct scsi_request *req;
int err; int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen; unsigned int in_len, out_len, bytes, opcode, cmdlen;
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; char *buffer = NULL;
if (!sic) if (!sic)
return -EINVAL; return -EINVAL;
@ -452,7 +453,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
err = PTR_ERR(rq); err = PTR_ERR(rq);
goto error_free_buffer; goto error_free_buffer;
} }
blk_rq_set_block_pc(rq); req = scsi_req(rq);
scsi_req_init(rq);
cmdlen = COMMAND_SIZE(opcode); cmdlen = COMMAND_SIZE(opcode);
@ -460,14 +462,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
* get command and data to send to device, if any * get command and data to send to device, if any
*/ */
err = -EFAULT; err = -EFAULT;
rq->cmd_len = cmdlen; req->cmd_len = cmdlen;
if (copy_from_user(rq->cmd, sic->data, cmdlen)) if (copy_from_user(req->cmd, sic->data, cmdlen))
goto error; goto error;
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error; goto error;
err = blk_verify_command(rq->cmd, mode & FMODE_WRITE); err = blk_verify_command(req->cmd, mode & FMODE_WRITE);
if (err) if (err)
goto error; goto error;
@ -503,18 +505,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
goto error; goto error;
} }
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
blk_execute_rq(q, disk, rq, 0); blk_execute_rq(q, disk, rq, 0);
err = rq->errors & 0xff; /* only 8 bit SCSI status */ err = rq->errors & 0xff; /* only 8 bit SCSI status */
if (err) { if (err) {
if (rq->sense_len && rq->sense) { if (req->sense_len && req->sense) {
bytes = (OMAX_SB_LEN > rq->sense_len) ? bytes = (OMAX_SB_LEN > req->sense_len) ?
rq->sense_len : OMAX_SB_LEN; req->sense_len : OMAX_SB_LEN;
if (copy_to_user(sic->data, rq->sense, bytes)) if (copy_to_user(sic->data, req->sense, bytes))
err = -EFAULT; err = -EFAULT;
} }
} else { } else {
@ -542,11 +540,11 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, WRITE, __GFP_RECLAIM); rq = blk_get_request(q, WRITE, __GFP_RECLAIM);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
blk_rq_set_block_pc(rq); scsi_req_init(rq);
rq->timeout = BLK_DEFAULT_SG_TIMEOUT; rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
rq->cmd[0] = cmd; scsi_req(rq)->cmd[0] = cmd;
rq->cmd[4] = data; scsi_req(rq)->cmd[4] = data;
rq->cmd_len = 6; scsi_req(rq)->cmd_len = 6;
err = blk_execute_rq(q, bd_disk, rq, 0); err = blk_execute_rq(q, bd_disk, rq, 0);
blk_put_request(rq); blk_put_request(rq);
@ -743,6 +741,18 @@ int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
} }
EXPORT_SYMBOL(scsi_cmd_blk_ioctl); EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
void scsi_req_init(struct request *rq)
{
struct scsi_request *req = scsi_req(rq);
rq->cmd_type = REQ_TYPE_BLOCK_PC;
memset(req->__cmd, 0, sizeof(req->__cmd));
req->cmd = req->__cmd;
req->cmd_len = BLK_MAX_CDB;
req->sense_len = 0;
}
EXPORT_SYMBOL(scsi_req_init);
static int __init blk_scsi_ioctl_init(void) static int __init blk_scsi_ioctl_init(void)
{ {
blk_set_cmd_filter_defaults(&blk_default_cmd_filter); blk_set_cmd_filter_defaults(&blk_default_cmd_filter);

Просмотреть файл

@ -1271,7 +1271,7 @@ static int atapi_drain_needed(struct request *rq)
if (!blk_rq_bytes(rq) || op_is_write(req_op(rq))) if (!blk_rq_bytes(rq) || op_is_write(req_op(rq)))
return 0; return 0;
return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC; return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC;
} }
static int ata_scsi_dev_config(struct scsi_device *sdev, static int ata_scsi_dev_config(struct scsi_device *sdev,

Просмотреть файл

@ -52,6 +52,7 @@
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/sg.h> #include <scsi/sg.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/scsi_request.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/kthread.h> #include <linux/kthread.h>
@ -1854,7 +1855,7 @@ static void cciss_softirq_done(struct request *rq)
/* set the residual count for pc requests */ /* set the residual count for pc requests */
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
rq->resid_len = c->err_info->ResidualCnt; scsi_req(rq)->resid_len = c->err_info->ResidualCnt;
blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO);
@ -1941,9 +1942,16 @@ static void cciss_get_serial_no(ctlr_info_t *h, int logvol,
static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
int drv_index) int drv_index)
{ {
disk->queue = blk_init_queue(do_cciss_request, &h->lock); disk->queue = blk_alloc_queue(GFP_KERNEL);
if (!disk->queue) if (!disk->queue)
goto init_queue_failure; goto init_queue_failure;
disk->queue->cmd_size = sizeof(struct scsi_request);
disk->queue->request_fn = do_cciss_request;
disk->queue->queue_lock = &h->lock;
if (blk_init_allocated_queue(disk->queue) < 0)
goto cleanup_queue;
sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index);
disk->major = h->major; disk->major = h->major;
disk->first_minor = drv_index << NWD_SHIFT; disk->first_minor = drv_index << NWD_SHIFT;
@ -3111,15 +3119,7 @@ static inline int evaluate_target_status(ctlr_info_t *h,
return error_value; return error_value;
} }
/* SG_IO or similar, copy sense data back */ scsi_req(cmd->rq)->sense_len = cmd->err_info->SenseLen;
if (cmd->rq->sense) {
if (cmd->rq->sense_len > cmd->err_info->SenseLen)
cmd->rq->sense_len = cmd->err_info->SenseLen;
memcpy(cmd->rq->sense, cmd->err_info->SenseInfo,
cmd->rq->sense_len);
} else
cmd->rq->sense_len = 0;
return error_value; return error_value;
} }
@ -3150,7 +3150,6 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
dev_warn(&h->pdev->dev, "cmd %p has" dev_warn(&h->pdev->dev, "cmd %p has"
" completed with data underrun " " completed with data underrun "
"reported\n", cmd); "reported\n", cmd);
cmd->rq->resid_len = cmd->err_info->ResidualCnt;
} }
break; break;
case CMD_DATA_OVERRUN: case CMD_DATA_OVERRUN:
@ -3426,8 +3425,9 @@ static void do_cciss_request(struct request_queue *q)
c->Request.CDB[14] = c->Request.CDB[15] = 0; c->Request.CDB[14] = c->Request.CDB[15] = 0;
} }
} else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) { } else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) {
c->Request.CDBLen = creq->cmd_len; c->Request.CDBLen = scsi_req(creq)->cmd_len;
memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); memcpy(c->Request.CDB, scsi_req(creq)->cmd, BLK_MAX_CDB);
scsi_req(creq)->sense = c->err_info->SenseInfo;
} else { } else {
dev_warn(&h->pdev->dev, "bad request type %d\n", dev_warn(&h->pdev->dev, "bad request type %d\n",
creq->cmd_type); creq->cmd_type);

Просмотреть файл

@ -707,7 +707,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
WRITE : READ, __GFP_RECLAIM); WRITE : READ, __GFP_RECLAIM);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
blk_rq_set_block_pc(rq); scsi_req_init(rq);
if (cgc->buflen) { if (cgc->buflen) {
ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
@ -716,8 +716,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
goto out; goto out;
} }
rq->cmd_len = COMMAND_SIZE(cgc->cmd[0]); scsi_req(rq)->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); memcpy(scsi_req(rq)->cmd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ; rq->timeout = 60*HZ;
if (cgc->quiet) if (cgc->quiet)

Просмотреть файл

@ -52,6 +52,7 @@ struct virtio_blk {
}; };
struct virtblk_req { struct virtblk_req {
struct scsi_request sreq; /* for SCSI passthrough */
struct request *req; struct request *req;
struct virtio_blk_outhdr out_hdr; struct virtio_blk_outhdr out_hdr;
struct virtio_scsi_inhdr in_hdr; struct virtio_scsi_inhdr in_hdr;
@ -91,7 +92,7 @@ static int __virtblk_add_req(struct virtqueue *vq,
* inhdr with additional status information. * inhdr with additional status information.
*/ */
if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { 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->sreq.cmd, vbr->sreq.cmd_len);
sgs[num_out++] = &cmd; sgs[num_out++] = &cmd;
} }
@ -103,7 +104,6 @@ static int __virtblk_add_req(struct virtqueue *vq,
} }
if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
memcpy(vbr->sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE); sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE);
sgs[num_out + num_in++] = &sense; sgs[num_out + num_in++] = &sense;
sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr)); sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
@ -123,8 +123,10 @@ static inline void virtblk_request_done(struct request *req)
int error = virtblk_result(vbr); int error = virtblk_result(vbr);
if (req->cmd_type == REQ_TYPE_BLOCK_PC) { if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual); scsi_req(req)->resid_len =
req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len); virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
vbr->sreq.sense_len =
virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors); req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
} else if (req->cmd_type == REQ_TYPE_DRV_PRIV) { } else if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
req->errors = (error != 0); req->errors = (error != 0);
@ -538,6 +540,7 @@ static int virtblk_init_request(void *data, struct request *rq,
struct virtio_blk *vblk = data; struct virtio_blk *vblk = data;
struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq); struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
vbr->sreq.sense = vbr->sense;
sg_init_table(vbr->sg, vblk->sg_elems); sg_init_table(vbr->sg, vblk->sg_elems);
return 0; return 0;
} }

Просмотреть файл

@ -281,8 +281,8 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/times.h> #include <linux/times.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <scsi/scsi_request.h>
/* used to tell the module to turn on full debugging messages */ /* used to tell the module to turn on full debugging messages */
static bool debug; static bool debug;
@ -2172,6 +2172,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
{ {
struct request_queue *q = cdi->disk->queue; struct request_queue *q = cdi->disk->queue;
struct request *rq; struct request *rq;
struct scsi_request *req;
struct bio *bio; struct bio *bio;
unsigned int len; unsigned int len;
int nr, ret = 0; int nr, ret = 0;
@ -2195,7 +2196,8 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
ret = PTR_ERR(rq); ret = PTR_ERR(rq);
break; break;
} }
blk_rq_set_block_pc(rq); req = scsi_req(rq);
scsi_req_init(rq);
ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL); ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
if (ret) { if (ret) {
@ -2203,23 +2205,23 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
break; break;
} }
rq->cmd[0] = GPCMD_READ_CD; req->cmd[0] = GPCMD_READ_CD;
rq->cmd[1] = 1 << 2; req->cmd[1] = 1 << 2;
rq->cmd[2] = (lba >> 24) & 0xff; req->cmd[2] = (lba >> 24) & 0xff;
rq->cmd[3] = (lba >> 16) & 0xff; req->cmd[3] = (lba >> 16) & 0xff;
rq->cmd[4] = (lba >> 8) & 0xff; req->cmd[4] = (lba >> 8) & 0xff;
rq->cmd[5] = lba & 0xff; req->cmd[5] = lba & 0xff;
rq->cmd[6] = (nr >> 16) & 0xff; req->cmd[6] = (nr >> 16) & 0xff;
rq->cmd[7] = (nr >> 8) & 0xff; req->cmd[7] = (nr >> 8) & 0xff;
rq->cmd[8] = nr & 0xff; req->cmd[8] = nr & 0xff;
rq->cmd[9] = 0xf8; req->cmd[9] = 0xf8;
rq->cmd_len = 12; req->cmd_len = 12;
rq->timeout = 60 * HZ; rq->timeout = 60 * HZ;
bio = rq->bio; bio = rq->bio;
if (blk_execute_rq(q, cdi->disk, rq, 0)) { if (blk_execute_rq(q, cdi->disk, rq, 0)) {
struct request_sense *s = rq->sense; struct request_sense *s = req->sense;
ret = -EIO; ret = -EIO;
cdi->last_sense = s->sense_key; cdi->last_sense = s->sense_key;
} }

Просмотреть файл

@ -93,6 +93,7 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
int error; int error;
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->special = (char *)pc; rq->special = (char *)pc;
@ -103,9 +104,9 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
goto put_req; goto put_req;
} }
memcpy(rq->cmd, pc->c, 12); memcpy(scsi_req(rq)->cmd, pc->c, 12);
if (drive->media == ide_tape) if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1; scsi_req(rq)->cmd[13] = REQ_IDETAPE_PC1;
error = blk_execute_rq(drive->queue, disk, rq, 0); error = blk_execute_rq(drive->queue, disk, rq, 0);
put_req: put_req:
blk_put_request(rq); blk_put_request(rq);
@ -171,7 +172,8 @@ EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
void ide_prep_sense(ide_drive_t *drive, struct request *rq) void ide_prep_sense(ide_drive_t *drive, struct request *rq)
{ {
struct request_sense *sense = &drive->sense_data; struct request_sense *sense = &drive->sense_data;
struct request *sense_rq = &drive->sense_rq; struct request *sense_rq = drive->sense_rq;
struct scsi_request *req = scsi_req(sense_rq);
unsigned int cmd_len, sense_len; unsigned int cmd_len, sense_len;
int err; int err;
@ -197,6 +199,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
memset(sense, 0, sizeof(*sense)); memset(sense, 0, sizeof(*sense));
blk_rq_init(rq->q, sense_rq); blk_rq_init(rq->q, sense_rq);
scsi_req_init(sense_rq);
err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
GFP_NOIO); GFP_NOIO);
@ -208,13 +211,13 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
} }
sense_rq->rq_disk = rq->rq_disk; sense_rq->rq_disk = rq->rq_disk;
sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
sense_rq->cmd[4] = cmd_len;
sense_rq->cmd_type = REQ_TYPE_ATA_SENSE; sense_rq->cmd_type = REQ_TYPE_ATA_SENSE;
sense_rq->rq_flags |= RQF_PREEMPT; sense_rq->rq_flags |= RQF_PREEMPT;
req->cmd[0] = GPCMD_REQUEST_SENSE;
req->cmd[4] = cmd_len;
if (drive->media == ide_tape) if (drive->media == ide_tape)
sense_rq->cmd[13] = REQ_IDETAPE_PC1; req->cmd[13] = REQ_IDETAPE_PC1;
drive->sense_rq_armed = true; drive->sense_rq_armed = true;
} }
@ -229,12 +232,12 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
return -ENOMEM; return -ENOMEM;
} }
drive->sense_rq.special = special; drive->sense_rq->special = special;
drive->sense_rq_armed = false; drive->sense_rq_armed = false;
drive->hwif->rq = NULL; drive->hwif->rq = NULL;
elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT); elv_add_request(drive->queue, drive->sense_rq, ELEVATOR_INSERT_FRONT);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ide_queue_sense_rq); EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
@ -247,14 +250,14 @@ EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
void ide_retry_pc(ide_drive_t *drive) void ide_retry_pc(ide_drive_t *drive)
{ {
struct request *failed_rq = drive->hwif->rq; struct request *failed_rq = drive->hwif->rq;
struct request *sense_rq = &drive->sense_rq; struct request *sense_rq = drive->sense_rq;
struct ide_atapi_pc *pc = &drive->request_sense_pc; struct ide_atapi_pc *pc = &drive->request_sense_pc;
(void)ide_read_error(drive); (void)ide_read_error(drive);
/* init pc from sense_rq */ /* init pc from sense_rq */
ide_init_pc(pc); ide_init_pc(pc);
memcpy(pc->c, sense_rq->cmd, 12); memcpy(pc->c, scsi_req(sense_rq)->cmd, 12);
if (drive->media == ide_tape) if (drive->media == ide_tape)
drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
@ -286,7 +289,7 @@ int ide_cd_expiry(ide_drive_t *drive)
* commands/drives support that. Let ide_timer_expiry keep polling us * commands/drives support that. Let ide_timer_expiry keep polling us
* for these. * for these.
*/ */
switch (rq->cmd[0]) { switch (scsi_req(rq)->cmd[0]) {
case GPCMD_BLANK: case GPCMD_BLANK:
case GPCMD_FORMAT_UNIT: case GPCMD_FORMAT_UNIT:
case GPCMD_RESERVE_RZONE_TRACK: case GPCMD_RESERVE_RZONE_TRACK:
@ -297,7 +300,7 @@ int ide_cd_expiry(ide_drive_t *drive)
default: default:
if (!(rq->rq_flags & RQF_QUIET)) if (!(rq->rq_flags & RQF_QUIET))
printk(KERN_INFO PFX "cmd 0x%x timed out\n", printk(KERN_INFO PFX "cmd 0x%x timed out\n",
rq->cmd[0]); scsi_req(rq)->cmd[0]);
wait = 0; wait = 0;
break; break;
} }
@ -420,7 +423,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
? "write" : "read"); ? "write" : "read");
pc->flags |= PC_FLAG_DMA_ERROR; pc->flags |= PC_FLAG_DMA_ERROR;
} else } else
rq->resid_len = 0; scsi_req(rq)->resid_len = 0;
debug_log("%s: DMA finished\n", drive->name); debug_log("%s: DMA finished\n", drive->name);
} }
@ -436,7 +439,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
local_irq_enable_in_hardirq(); local_irq_enable_in_hardirq();
if (drive->media == ide_tape && if (drive->media == ide_tape &&
(stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) (stat & ATA_ERR) && scsi_req(rq)->cmd[0] == REQUEST_SENSE)
stat &= ~ATA_ERR; stat &= ~ATA_ERR;
if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) { if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) {
@ -446,7 +449,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (drive->media != ide_tape) if (drive->media != ide_tape)
pc->rq->errors++; pc->rq->errors++;
if (rq->cmd[0] == REQUEST_SENSE) { if (scsi_req(rq)->cmd[0] == REQUEST_SENSE) {
printk(KERN_ERR PFX "%s: I/O error in request " printk(KERN_ERR PFX "%s: I/O error in request "
"sense command\n", drive->name); "sense command\n", drive->name);
return ide_do_reset(drive); return ide_do_reset(drive);
@ -512,7 +515,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
ide_pio_bytes(drive, cmd, write, done); ide_pio_bytes(drive, cmd, write, done);
/* Update transferred byte count */ /* Update transferred byte count */
rq->resid_len -= done; scsi_req(rq)->resid_len -= done;
bcount -= done; bcount -= done;
@ -520,7 +523,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
ide_pad_transfer(drive, write, bcount); ide_pad_transfer(drive, write, bcount);
debug_log("[cmd %x] transferred %d bytes, padded %d bytes, resid: %u\n", debug_log("[cmd %x] transferred %d bytes, padded %d bytes, resid: %u\n",
rq->cmd[0], done, bcount, rq->resid_len); rq->cmd[0], done, bcount, scsi_req(rq)->resid_len);
/* And set the interrupt handler again */ /* And set the interrupt handler again */
ide_set_handler(drive, ide_pc_intr, timeout); ide_set_handler(drive, ide_pc_intr, timeout);
@ -603,7 +606,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
if (dev_is_idecd(drive)) { if (dev_is_idecd(drive)) {
/* ATAPI commands get padded out to 12 bytes minimum */ /* ATAPI commands get padded out to 12 bytes minimum */
cmd_len = COMMAND_SIZE(rq->cmd[0]); cmd_len = COMMAND_SIZE(scsi_req(rq)->cmd[0]);
if (cmd_len < ATAPI_MIN_CDB_BYTES) if (cmd_len < ATAPI_MIN_CDB_BYTES)
cmd_len = ATAPI_MIN_CDB_BYTES; cmd_len = ATAPI_MIN_CDB_BYTES;
@ -650,7 +653,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
/* Send the actual packet */ /* Send the actual packet */
if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); hwif->tp_ops->output_data(drive, NULL, scsi_req(rq)->cmd, cmd_len);
/* Begin DMA, if necessary */ /* Begin DMA, if necessary */
if (dev_is_idecd(drive)) { if (dev_is_idecd(drive)) {
@ -695,7 +698,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
bytes, 63 * 1024)); bytes, 63 * 1024));
/* We haven't transferred any data yet */ /* We haven't transferred any data yet */
rq->resid_len = bcount; scsi_req(rq)->resid_len = bcount;
if (pc->flags & PC_FLAG_DMA_ERROR) { if (pc->flags & PC_FLAG_DMA_ERROR) {
pc->flags &= ~PC_FLAG_DMA_ERROR; pc->flags &= ~PC_FLAG_DMA_ERROR;

Просмотреть файл

@ -121,7 +121,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq)
* don't log START_STOP unit with LoEj set, since we cannot * don't log START_STOP unit with LoEj set, since we cannot
* reliably check if drive can auto-close * reliably check if drive can auto-close
*/ */
if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
break; break;
log = 1; log = 1;
break; break;
@ -163,7 +163,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
* toc has not been recorded yet, it will fail with 05/24/00 (which is a * toc has not been recorded yet, it will fail with 05/24/00 (which is a
* confusing error) * confusing error)
*/ */
if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP) if (failed_command && scsi_req(failed_command)->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
if (sense->sense_key == 0x05 && sense->asc == 0x24) if (sense->sense_key == 0x05 && sense->asc == 0x24)
return; return;
@ -219,15 +219,12 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
void *sense = bio_data(rq->bio); void *sense = bio_data(rq->bio);
if (failed) { if (failed) {
if (failed->sense) { /*
/* * Sense is always read into drive->sense_data, copy back to the
* Sense is always read into drive->sense_data. * original request.
* Copy back if the failed request has its */
* sense pointer set. memcpy(scsi_req(failed)->sense, sense, 18);
*/ scsi_req(failed)->sense_len = scsi_req(rq)->sense_len;
memcpy(failed->sense, sense, 18);
failed->sense_len = rq->sense_len;
}
cdrom_analyze_sense_data(drive, failed); cdrom_analyze_sense_data(drive, failed);
if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
@ -338,7 +335,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
* *
* cdrom_log_sense() knows this! * cdrom_log_sense() knows this!
*/ */
if (rq->cmd[0] == GPCMD_START_STOP_UNIT) if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT)
break; break;
/* fall-through */ /* fall-through */
case DATA_PROTECT: case DATA_PROTECT:
@ -414,7 +411,7 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
* Some of the trailing request sense fields are optional, * Some of the trailing request sense fields are optional,
* and some drives don't send them. Sigh. * and some drives don't send them. Sigh.
*/ */
if (rq->cmd[0] == GPCMD_REQUEST_SENSE && if (scsi_req(rq)->cmd[0] == GPCMD_REQUEST_SENSE &&
cmd->nleft > 0 && cmd->nleft <= 5) cmd->nleft > 0 && cmd->nleft <= 5)
cmd->nleft = 0; cmd->nleft = 0;
} }
@ -425,12 +422,8 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
req_flags_t rq_flags) req_flags_t rq_flags)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct request_sense local_sense;
int retries = 10; int retries = 10;
req_flags_t flags = 0; bool failed;
if (!sense)
sense = &local_sense;
ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
"rq_flags: 0x%x", "rq_flags: 0x%x",
@ -440,12 +433,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
do { do {
struct request *rq; struct request *rq;
int error; int error;
bool delay = false;
rq = blk_get_request(drive->queue, write, __GFP_RECLAIM); rq = blk_get_request(drive->queue, write, __GFP_RECLAIM);
scsi_req_init(rq);
memcpy(rq->cmd, cmd, BLK_MAX_CDB); memcpy(scsi_req(rq)->cmd, cmd, BLK_MAX_CDB);
rq->cmd_type = REQ_TYPE_ATA_PC; rq->cmd_type = REQ_TYPE_ATA_PC;
rq->sense = sense;
rq->rq_flags |= rq_flags; rq->rq_flags |= rq_flags;
rq->timeout = timeout; rq->timeout = timeout;
if (buffer) { if (buffer) {
@ -460,21 +453,21 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
error = blk_execute_rq(drive->queue, info->disk, rq, 0); error = blk_execute_rq(drive->queue, info->disk, rq, 0);
if (buffer) if (buffer)
*bufflen = rq->resid_len; *bufflen = scsi_req(rq)->resid_len;
if (sense)
flags = rq->rq_flags; memcpy(sense, scsi_req(rq)->sense, sizeof(*sense));
blk_put_request(rq);
/* /*
* FIXME: we should probably abort/retry or something in case of * FIXME: we should probably abort/retry or something in case of
* failure. * failure.
*/ */
if (flags & RQF_FAILED) { failed = (rq->rq_flags & RQF_FAILED) != 0;
if (failed) {
/* /*
* The request failed. Retry if it was due to a unit * The request failed. Retry if it was due to a unit
* attention status (usually means media was changed). * attention status (usually means media was changed).
*/ */
struct request_sense *reqbuf = sense; struct request_sense *reqbuf = scsi_req(rq)->sense;
if (reqbuf->sense_key == UNIT_ATTENTION) if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change(drive); cdrom_saw_media_change(drive);
@ -485,19 +478,20 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
* a disk. Retry, but wait a little to give * a disk. Retry, but wait a little to give
* the drive time to complete the load. * the drive time to complete the load.
*/ */
ssleep(2); delay = true;
} else { } else {
/* otherwise, don't retry */ /* otherwise, don't retry */
retries = 0; retries = 0;
} }
--retries; --retries;
} }
blk_put_request(rq);
/* end of retry loop */ if (delay)
} while ((flags & RQF_FAILED) && retries >= 0); ssleep(2);
} while (failed && retries >= 0);
/* return an error if the command failed */ /* return an error if the command failed */
return (flags & RQF_FAILED) ? -EIO : 0; return failed ? -EIO : 0;
} }
/* /*
@ -636,7 +630,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
len -= blen; len -= blen;
if (sense && write == 0) if (sense && write == 0)
rq->sense_len += blen; scsi_req(rq)->sense_len += blen;
} }
/* pad, if necessary */ /* pad, if necessary */
@ -664,7 +658,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
out_end: out_end:
if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) { if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) {
rq->resid_len = 0; scsi_req(rq)->resid_len = 0;
blk_end_request_all(rq, 0); blk_end_request_all(rq, 0);
hwif->rq = NULL; hwif->rq = NULL;
} else { } else {
@ -685,9 +679,9 @@ out_end:
/* make sure it's fully ended */ /* make sure it's fully ended */
if (rq->cmd_type != REQ_TYPE_FS) { if (rq->cmd_type != REQ_TYPE_FS) {
rq->resid_len -= cmd->nbytes - cmd->nleft; scsi_req(rq)->resid_len -= cmd->nbytes - cmd->nleft;
if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
rq->resid_len += cmd->last_xfer_len; scsi_req(rq)->resid_len += cmd->last_xfer_len;
} }
ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq)); ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq));
@ -1312,28 +1306,29 @@ static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
int hard_sect = queue_logical_block_size(q); int hard_sect = queue_logical_block_size(q);
long block = (long)blk_rq_pos(rq) / (hard_sect >> 9); long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
struct scsi_request *req = scsi_req(rq);
memset(rq->cmd, 0, BLK_MAX_CDB); memset(req->cmd, 0, BLK_MAX_CDB);
if (rq_data_dir(rq) == READ) if (rq_data_dir(rq) == READ)
rq->cmd[0] = GPCMD_READ_10; req->cmd[0] = GPCMD_READ_10;
else else
rq->cmd[0] = GPCMD_WRITE_10; req->cmd[0] = GPCMD_WRITE_10;
/* /*
* fill in lba * fill in lba
*/ */
rq->cmd[2] = (block >> 24) & 0xff; req->cmd[2] = (block >> 24) & 0xff;
rq->cmd[3] = (block >> 16) & 0xff; req->cmd[3] = (block >> 16) & 0xff;
rq->cmd[4] = (block >> 8) & 0xff; req->cmd[4] = (block >> 8) & 0xff;
rq->cmd[5] = block & 0xff; req->cmd[5] = block & 0xff;
/* /*
* and transfer length * and transfer length
*/ */
rq->cmd[7] = (blocks >> 8) & 0xff; req->cmd[7] = (blocks >> 8) & 0xff;
rq->cmd[8] = blocks & 0xff; req->cmd[8] = blocks & 0xff;
rq->cmd_len = 10; req->cmd_len = 10;
return BLKPREP_OK; return BLKPREP_OK;
} }
@ -1343,7 +1338,7 @@ static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
*/ */
static int ide_cdrom_prep_pc(struct request *rq) static int ide_cdrom_prep_pc(struct request *rq)
{ {
u8 *c = rq->cmd; u8 *c = scsi_req(rq)->cmd;
/* transform 6-byte read/write commands to the 10-byte version */ /* transform 6-byte read/write commands to the 10-byte version */
if (c[0] == READ_6 || c[0] == WRITE_6) { if (c[0] == READ_6 || c[0] == WRITE_6) {
@ -1354,7 +1349,7 @@ static int ide_cdrom_prep_pc(struct request *rq)
c[2] = 0; c[2] = 0;
c[1] &= 0xe0; c[1] &= 0xe0;
c[0] += (READ_10 - READ_6); c[0] += (READ_10 - READ_6);
rq->cmd_len = 10; scsi_req(rq)->cmd_len = 10;
return BLKPREP_OK; return BLKPREP_OK;
} }

Просмотреть файл

@ -304,6 +304,7 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
int ret; int ret;
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->rq_flags = RQF_QUIET; rq->rq_flags = RQF_QUIET;
ret = blk_execute_rq(drive->queue, cd->disk, rq, 0); ret = blk_execute_rq(drive->queue, cd->disk, rq, 0);

Просмотреть файл

@ -315,12 +315,12 @@ void ide_cd_log_error(const char *name, struct request *failed_command,
while (hi > lo) { while (hi > lo) {
mid = (lo + hi) / 2; mid = (lo + hi) / 2;
if (packet_command_texts[mid].packet_command == if (packet_command_texts[mid].packet_command ==
failed_command->cmd[0]) { scsi_req(failed_command)->cmd[0]) {
s = packet_command_texts[mid].text; s = packet_command_texts[mid].text;
break; break;
} }
if (packet_command_texts[mid].packet_command > if (packet_command_texts[mid].packet_command >
failed_command->cmd[0]) scsi_req(failed_command)->cmd[0])
hi = mid; hi = mid;
else else
lo = mid + 1; lo = mid + 1;
@ -329,7 +329,7 @@ void ide_cd_log_error(const char *name, struct request *failed_command,
printk(KERN_ERR " The failed \"%s\" packet command " printk(KERN_ERR " The failed \"%s\" packet command "
"was: \n \"", s); "was: \n \"", s);
for (i = 0; i < BLK_MAX_CDB; i++) for (i = 0; i < BLK_MAX_CDB; i++)
printk(KERN_CONT "%02x ", failed_command->cmd[i]); printk(KERN_CONT "%02x ", scsi_req(failed_command)->cmd[i]);
printk(KERN_CONT "\"\n"); printk(KERN_CONT "\"\n");
} }

Просмотреть файл

@ -166,10 +166,11 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
return setting->set(drive, arg); return setting->set(drive, arg);
rq = blk_get_request(q, READ, __GFP_RECLAIM); rq = blk_get_request(q, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->cmd_len = 5; scsi_req(rq)->cmd_len = 5;
rq->cmd[0] = REQ_DEVSET_EXEC; scsi_req(rq)->cmd[0] = REQ_DEVSET_EXEC;
*(int *)&rq->cmd[1] = arg; *(int *)&scsi_req(rq)->cmd[1] = arg;
rq->special = setting->set; rq->special = setting->set;
if (blk_execute_rq(q, NULL, rq, 0)) if (blk_execute_rq(q, NULL, rq, 0))
@ -183,7 +184,7 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
{ {
int err, (*setfunc)(ide_drive_t *, int) = rq->special; int err, (*setfunc)(ide_drive_t *, int) = rq->special;
err = setfunc(drive, *(int *)&rq->cmd[1]); err = setfunc(drive, *(int *)&scsi_req(rq)->cmd[1]);
if (err) if (err)
rq->errors = err; rq->errors = err;
ide_complete_rq(drive, err, blk_rq_bytes(rq)); ide_complete_rq(drive, err, blk_rq_bytes(rq));

Просмотреть файл

@ -478,6 +478,7 @@ static int set_multcount(ide_drive_t *drive, int arg)
return -EBUSY; return -EBUSY;
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->mult_req = arg; drive->mult_req = arg;

Просмотреть файл

@ -148,7 +148,7 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
struct request *rq = drive->hwif->rq; struct request *rq = drive->hwif->rq;
if (rq && rq->cmd_type == REQ_TYPE_DRV_PRIV && if (rq && rq->cmd_type == REQ_TYPE_DRV_PRIV &&
rq->cmd[0] == REQ_DRIVE_RESET) { scsi_req(rq)->cmd[0] == REQ_DRIVE_RESET) {
if (err <= 0 && rq->errors == 0) if (err <= 0 && rq->errors == 0)
rq->errors = -EIO; rq->errors = -EIO;
ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq)); ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq));

Просмотреть файл

@ -203,7 +203,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
memcpy(rq->cmd, pc->c, 12); memcpy(scsi_req(rq)->cmd, pc->c, 12);
pc->rq = rq; pc->rq = rq;
if (cmd == WRITE) if (cmd == WRITE)
@ -216,7 +216,7 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
struct ide_atapi_pc *pc, struct request *rq) struct ide_atapi_pc *pc, struct request *rq)
{ {
ide_init_pc(pc); ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c)); memcpy(pc->c, scsi_req(rq)->cmd, sizeof(pc->c));
pc->rq = rq; pc->rq = rq;
if (blk_rq_bytes(rq)) { if (blk_rq_bytes(rq)) {
pc->flags |= PC_FLAG_DMA_OK; pc->flags |= PC_FLAG_DMA_OK;

Просмотреть файл

@ -279,7 +279,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{ {
u8 cmd = rq->cmd[0]; u8 cmd = scsi_req(rq)->cmd[0];
switch (cmd) { switch (cmd) {
case REQ_PARK_HEADS: case REQ_PARK_HEADS:
@ -545,6 +545,7 @@ repeat:
goto plug_device; goto plug_device;
} }
scsi_req(rq)->resid_len = blk_rq_bytes(rq);
hwif->rq = rq; hwif->rq = rq;
spin_unlock_irq(&hwif->lock); spin_unlock_irq(&hwif->lock);

Просмотреть файл

@ -126,6 +126,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
struct request *rq; struct request *rq;
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
err = blk_execute_rq(drive->queue, NULL, rq, 0); err = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq); blk_put_request(rq);
@ -222,9 +223,10 @@ static int generic_drive_reset(ide_drive_t *drive)
int ret = 0; int ret = 0;
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->cmd_len = 1; scsi_req(rq)->cmd_len = 1;
rq->cmd[0] = REQ_DRIVE_RESET; scsi_req(rq)->cmd[0] = REQ_DRIVE_RESET;
if (blk_execute_rq(drive->queue, NULL, rq, 1)) if (blk_execute_rq(drive->queue, NULL, rq, 1))
ret = rq->errors; ret = rq->errors;
blk_put_request(rq); blk_put_request(rq);

Просмотреть файл

@ -32,8 +32,9 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
spin_unlock_irq(&hwif->lock); spin_unlock_irq(&hwif->lock);
rq = blk_get_request(q, READ, __GFP_RECLAIM); rq = blk_get_request(q, READ, __GFP_RECLAIM);
rq->cmd[0] = REQ_PARK_HEADS; scsi_req_init(rq);
rq->cmd_len = 1; scsi_req(rq)->cmd[0] = REQ_PARK_HEADS;
scsi_req(rq)->cmd_len = 1;
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->special = &timeout; rq->special = &timeout;
rc = blk_execute_rq(q, NULL, rq, 1); rc = blk_execute_rq(q, NULL, rq, 1);
@ -46,11 +47,12 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
* timeout has expired, so power management will be reenabled. * timeout has expired, so power management will be reenabled.
*/ */
rq = blk_get_request(q, READ, GFP_NOWAIT); rq = blk_get_request(q, READ, GFP_NOWAIT);
scsi_req_init(rq);
if (IS_ERR(rq)) if (IS_ERR(rq))
goto out; goto out;
rq->cmd[0] = REQ_UNPARK_HEADS; scsi_req(rq)->cmd[0] = REQ_UNPARK_HEADS;
rq->cmd_len = 1; scsi_req(rq)->cmd_len = 1;
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
elv_add_request(q, rq, ELEVATOR_INSERT_FRONT); elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
@ -64,7 +66,7 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
struct ide_taskfile *tf = &cmd.tf; struct ide_taskfile *tf = &cmd.tf;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
if (rq->cmd[0] == REQ_PARK_HEADS) { if (scsi_req(rq)->cmd[0] == REQ_PARK_HEADS) {
drive->sleep = *(unsigned long *)rq->special; drive->sleep = *(unsigned long *)rq->special;
drive->dev_flags |= IDE_DFLAG_SLEEPING; drive->dev_flags |= IDE_DFLAG_SLEEPING;
tf->command = ATA_CMD_IDLEIMMEDIATE; tf->command = ATA_CMD_IDLEIMMEDIATE;

Просмотреть файл

@ -19,6 +19,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_ATA_PM_SUSPEND; rq->cmd_type = REQ_TYPE_ATA_PM_SUSPEND;
rq->special = &rqpm; rq->special = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND; rqpm.pm_step = IDE_PM_START_SUSPEND;
@ -89,6 +90,7 @@ int generic_ide_resume(struct device *dev)
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_ATA_PM_RESUME; rq->cmd_type = REQ_TYPE_ATA_PM_RESUME;
rq->rq_flags |= RQF_PREEMPT; rq->rq_flags |= RQF_PREEMPT;
rq->special = &rqpm; rq->special = &rqpm;

Просмотреть файл

@ -741,6 +741,14 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
} }
} }
static int ide_init_rq(struct request_queue *q, struct request *rq, gfp_t gfp)
{
struct ide_request *req = blk_mq_rq_to_pdu(rq);
req->sreq.sense = req->sense;
return 0;
}
/* /*
* init request queue * init request queue
*/ */
@ -758,11 +766,18 @@ static int ide_init_queue(ide_drive_t *drive)
* limits and LBA48 we could raise it but as yet * limits and LBA48 we could raise it but as yet
* do not. * do not.
*/ */
q = blk_alloc_queue_node(GFP_KERNEL, hwif_to_node(hwif));
q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));
if (!q) if (!q)
return 1; return 1;
q->request_fn = do_ide_request;
q->init_rq_fn = ide_init_rq;
q->cmd_size = sizeof(struct ide_request);
if (blk_init_allocated_queue(q) < 0) {
blk_cleanup_queue(q);
return 1;
}
q->queuedata = drive; q->queuedata = drive;
blk_queue_segment_boundary(q, 0xffff); blk_queue_segment_boundary(q, 0xffff);
@ -1131,10 +1146,12 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
ide_port_for_each_dev(i, drive, hwif) { ide_port_for_each_dev(i, drive, hwif) {
u8 j = (hwif->index * MAX_DRIVES) + i; u8 j = (hwif->index * MAX_DRIVES) + i;
u16 *saved_id = drive->id; u16 *saved_id = drive->id;
struct request *saved_sense_rq = drive->sense_rq;
memset(drive, 0, sizeof(*drive)); memset(drive, 0, sizeof(*drive));
memset(saved_id, 0, SECTOR_SIZE); memset(saved_id, 0, SECTOR_SIZE);
drive->id = saved_id; drive->id = saved_id;
drive->sense_rq = saved_sense_rq;
drive->media = ide_disk; drive->media = ide_disk;
drive->select = (i << 4) | ATA_DEVICE_OBS; drive->select = (i << 4) | ATA_DEVICE_OBS;
@ -1241,6 +1258,7 @@ static void ide_port_free_devices(ide_hwif_t *hwif)
int i; int i;
ide_port_for_each_dev(i, drive, hwif) { ide_port_for_each_dev(i, drive, hwif) {
kfree(drive->sense_rq);
kfree(drive->id); kfree(drive->id);
kfree(drive); kfree(drive);
} }
@ -1248,11 +1266,10 @@ static void ide_port_free_devices(ide_hwif_t *hwif)
static int ide_port_alloc_devices(ide_hwif_t *hwif, int node) static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
{ {
ide_drive_t *drive;
int i; int i;
for (i = 0; i < MAX_DRIVES; i++) { for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive;
drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node); drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
if (drive == NULL) if (drive == NULL)
goto out_nomem; goto out_nomem;
@ -1267,12 +1284,21 @@ static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
*/ */
drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node); drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node);
if (drive->id == NULL) if (drive->id == NULL)
goto out_nomem; goto out_free_drive;
drive->sense_rq = kmalloc(sizeof(struct request) +
sizeof(struct ide_request), GFP_KERNEL);
if (!drive->sense_rq)
goto out_free_id;
hwif->devices[i] = drive; hwif->devices[i] = drive;
} }
return 0; return 0;
out_free_id:
kfree(drive->id);
out_free_drive:
kfree(drive);
out_nomem: out_nomem:
ide_port_free_devices(hwif); ide_port_free_devices(hwif);
return -ENOMEM; return -ENOMEM;

Просмотреть файл

@ -282,7 +282,7 @@ static void idetape_analyze_error(ide_drive_t *drive)
/* correct remaining bytes to transfer */ /* correct remaining bytes to transfer */
if (pc->flags & PC_FLAG_DMA_ERROR) if (pc->flags & PC_FLAG_DMA_ERROR)
rq->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]); scsi_req(rq)->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]);
/* /*
* If error was the result of a zero-length read or write command, * If error was the result of a zero-length read or write command,
@ -316,7 +316,7 @@ static void idetape_analyze_error(ide_drive_t *drive)
pc->flags |= PC_FLAG_ABORT; pc->flags |= PC_FLAG_ABORT;
} }
if (!(pc->flags & PC_FLAG_ABORT) && if (!(pc->flags & PC_FLAG_ABORT) &&
(blk_rq_bytes(rq) - rq->resid_len)) (blk_rq_bytes(rq) - scsi_req(rq)->resid_len))
pc->retries = IDETAPE_MAX_PC_RETRIES + 1; pc->retries = IDETAPE_MAX_PC_RETRIES + 1;
} }
} }
@ -348,7 +348,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
"itself - Aborting request!\n"); "itself - Aborting request!\n");
} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
unsigned int blocks = unsigned int blocks =
(blk_rq_bytes(rq) - rq->resid_len) / tape->blk_size; (blk_rq_bytes(rq) - scsi_req(rq)->resid_len) / tape->blk_size;
tape->avg_size += blocks * tape->blk_size; tape->avg_size += blocks * tape->blk_size;
@ -560,7 +560,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
pc->flags |= PC_FLAG_WRITING; pc->flags |= PC_FLAG_WRITING;
} }
memcpy(rq->cmd, pc->c, 12); memcpy(scsi_req(rq)->cmd, pc->c, 12);
} }
static ide_startstop_t idetape_do_request(ide_drive_t *drive, static ide_startstop_t idetape_do_request(ide_drive_t *drive,
@ -570,10 +570,11 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL; struct ide_atapi_pc *pc = NULL;
struct ide_cmd cmd; struct ide_cmd cmd;
struct scsi_request *req = scsi_req(rq);
u8 stat; u8 stat;
ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u", ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u",
rq->cmd[0], (unsigned long long)blk_rq_pos(rq), req->cmd[0], (unsigned long long)blk_rq_pos(rq),
blk_rq_sectors(rq)); blk_rq_sectors(rq));
BUG_ON(!(rq->cmd_type == REQ_TYPE_DRV_PRIV || BUG_ON(!(rq->cmd_type == REQ_TYPE_DRV_PRIV ||
@ -592,7 +593,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
stat = hwif->tp_ops->read_status(hwif); stat = hwif->tp_ops->read_status(hwif);
if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 &&
(rq->cmd[13] & REQ_IDETAPE_PC2) == 0) (req->cmd[13] & REQ_IDETAPE_PC2) == 0)
drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
if (drive->dev_flags & IDE_DFLAG_POST_RESET) { if (drive->dev_flags & IDE_DFLAG_POST_RESET) {
@ -609,7 +610,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
} else if (time_after(jiffies, tape->dsc_timeout)) { } else if (time_after(jiffies, tape->dsc_timeout)) {
printk(KERN_ERR "ide-tape: %s: DSC timeout\n", printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
tape->name); tape->name);
if (rq->cmd[13] & REQ_IDETAPE_PC2) { if (req->cmd[13] & REQ_IDETAPE_PC2) {
idetape_media_access_finished(drive); idetape_media_access_finished(drive);
return ide_stopped; return ide_stopped;
} else { } else {
@ -626,23 +627,23 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
tape->postponed_rq = false; tape->postponed_rq = false;
} }
if (rq->cmd[13] & REQ_IDETAPE_READ) { if (req->cmd[13] & REQ_IDETAPE_READ) {
pc = &tape->queued_pc; pc = &tape->queued_pc;
ide_tape_create_rw_cmd(tape, pc, rq, READ_6); ide_tape_create_rw_cmd(tape, pc, rq, READ_6);
goto out; goto out;
} }
if (rq->cmd[13] & REQ_IDETAPE_WRITE) { if (req->cmd[13] & REQ_IDETAPE_WRITE) {
pc = &tape->queued_pc; pc = &tape->queued_pc;
ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6); ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6);
goto out; goto out;
} }
if (rq->cmd[13] & REQ_IDETAPE_PC1) { if (req->cmd[13] & REQ_IDETAPE_PC1) {
pc = (struct ide_atapi_pc *)rq->special; pc = (struct ide_atapi_pc *)rq->special;
rq->cmd[13] &= ~(REQ_IDETAPE_PC1); req->cmd[13] &= ~(REQ_IDETAPE_PC1);
rq->cmd[13] |= REQ_IDETAPE_PC2; req->cmd[13] |= REQ_IDETAPE_PC2;
goto out; goto out;
} }
if (rq->cmd[13] & REQ_IDETAPE_PC2) { if (req->cmd[13] & REQ_IDETAPE_PC2) {
idetape_media_access_finished(drive); idetape_media_access_finished(drive);
return ide_stopped; return ide_stopped;
} }
@ -853,8 +854,9 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
BUG_ON(size < 0 || size % tape->blk_size); BUG_ON(size < 0 || size % tape->blk_size);
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM); rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_DRV_PRIV; rq->cmd_type = REQ_TYPE_DRV_PRIV;
rq->cmd[13] = cmd; scsi_req(rq)->cmd[13] = cmd;
rq->rq_disk = tape->disk; rq->rq_disk = tape->disk;
rq->__sector = tape->first_frame; rq->__sector = tape->first_frame;
@ -868,7 +870,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
blk_execute_rq(drive->queue, tape->disk, rq, 0); blk_execute_rq(drive->queue, tape->disk, rq, 0);
/* calculate the number of transferred bytes and update buffer state */ /* calculate the number of transferred bytes and update buffer state */
size -= rq->resid_len; size -= scsi_req(rq)->resid_len;
tape->cur = tape->buf; tape->cur = tape->buf;
if (cmd == REQ_IDETAPE_READ) if (cmd == REQ_IDETAPE_READ)
tape->valid = size; tape->valid = size;

Просмотреть файл

@ -431,6 +431,7 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE; int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
rq = blk_get_request(drive->queue, rw, __GFP_RECLAIM); rq = blk_get_request(drive->queue, rw, __GFP_RECLAIM);
scsi_req_init(rq);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
/* /*

Просмотреть файл

@ -54,7 +54,7 @@
#define DRV_NAME "sis5513" #define DRV_NAME "sis5513"
/* registers layout and init values are chipset family dependent */ /* registers layout and init values are chipset family dependent */
#undef ATA_16
#define ATA_16 0x01 #define ATA_16 0x01
#define ATA_33 0x02 #define ATA_33 0x02
#define ATA_66 0x03 #define ATA_66 0x03

Просмотреть файл

@ -2320,10 +2320,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
SmpPassthroughReply_t *smprep; SmpPassthroughReply_t *smprep;
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
memcpy(req->sense, smprep, sizeof(*smprep)); memcpy(scsi_req(req)->sense, smprep, sizeof(*smprep));
req->sense_len = sizeof(*smprep); scsi_req(req)->sense_len = sizeof(*smprep);
req->resid_len = 0; scsi_req(req)->resid_len = 0;
rsp->resid_len -= smprep->ResponseDataLength; scsi_req(rsp)->resid_len -= smprep->ResponseDataLength;
} else { } else {
printk(MYIOC_s_ERR_FMT printk(MYIOC_s_ERR_FMT
"%s: smp passthru reply failed to be returned\n", "%s: smp passthru reply failed to be returned\n",

Просмотреть файл

@ -2095,7 +2095,7 @@ int fc_lport_bsg_request(struct bsg_job *job)
bsg_reply->reply_payload_rcv_len = 0; bsg_reply->reply_payload_rcv_len = 0;
if (rsp) 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); mutex_lock(&lport->lp_mutex);

Просмотреть файл

@ -2174,12 +2174,12 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
bio_data(rsp->bio), blk_rq_bytes(rsp)); bio_data(rsp->bio), blk_rq_bytes(rsp));
if (ret > 0) { if (ret > 0) {
/* positive number is the untransferred residual */ /* positive number is the untransferred residual */
rsp->resid_len = ret; scsi_req(rsp)->resid_len = ret;
req->resid_len = 0; scsi_req(req)->resid_len = 0;
ret = 0; ret = 0;
} else if (ret == 0) { } else if (ret == 0) {
rsp->resid_len = 0; scsi_req(rsp)->resid_len = 0;
req->resid_len = 0; scsi_req(req)->resid_len = 0;
} }
return ret; return ret;

Просмотреть файл

@ -274,15 +274,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
switch (req_data[1]) { switch (req_data[1]) {
case SMP_REPORT_GENERAL: case SMP_REPORT_GENERAL:
req->resid_len -= 8; scsi_req(req)->resid_len -= 8;
rsp->resid_len -= 32; scsi_req(rsp)->resid_len -= 32;
resp_data[2] = SMP_RESP_FUNC_ACC; resp_data[2] = SMP_RESP_FUNC_ACC;
resp_data[9] = sas_ha->num_phys; resp_data[9] = sas_ha->num_phys;
break; break;
case SMP_REPORT_MANUF_INFO: case SMP_REPORT_MANUF_INFO:
req->resid_len -= 8; scsi_req(req)->resid_len -= 8;
rsp->resid_len -= 64; scsi_req(rsp)->resid_len -= 64;
resp_data[2] = SMP_RESP_FUNC_ACC; resp_data[2] = SMP_RESP_FUNC_ACC;
memcpy(resp_data + 12, shost->hostt->name, memcpy(resp_data + 12, shost->hostt->name,
SAS_EXPANDER_VENDOR_ID_LEN); SAS_EXPANDER_VENDOR_ID_LEN);
@ -295,13 +295,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break; break;
case SMP_DISCOVER: case SMP_DISCOVER:
req->resid_len -= 16; scsi_req(req)->resid_len -= 16;
if ((int)req->resid_len < 0) { if ((int)scsi_req(req)->resid_len < 0) {
req->resid_len = 0; scsi_req(req)->resid_len = 0;
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
rsp->resid_len -= 56; scsi_req(rsp)->resid_len -= 56;
sas_host_smp_discover(sas_ha, resp_data, req_data[9]); sas_host_smp_discover(sas_ha, resp_data, req_data[9]);
break; break;
@ -311,13 +311,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break; break;
case SMP_REPORT_PHY_SATA: case SMP_REPORT_PHY_SATA:
req->resid_len -= 16; scsi_req(req)->resid_len -= 16;
if ((int)req->resid_len < 0) { if ((int)scsi_req(req)->resid_len < 0) {
req->resid_len = 0; scsi_req(req)->resid_len = 0;
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
rsp->resid_len -= 60; scsi_req(rsp)->resid_len -= 60;
sas_report_phy_sata(sas_ha, resp_data, req_data[9]); sas_report_phy_sata(sas_ha, resp_data, req_data[9]);
break; break;
@ -331,15 +331,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
int to_write = req_data[4]; int to_write = req_data[4];
if (blk_rq_bytes(req) < base_frame_size + to_write * 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; resp_data[2] = SMP_RESP_INV_FRM_LEN;
break; break;
} }
to_write = sas_host_smp_write_gpio(sas_ha, resp_data, req_data[2], to_write = sas_host_smp_write_gpio(sas_ha, resp_data, req_data[2],
req_data[3], to_write, &req_data[8]); req_data[3], to_write, &req_data[8]);
req->resid_len -= base_frame_size + to_write * 4; scsi_req(req)->resid_len -= base_frame_size + to_write * 4;
rsp->resid_len -= 8; scsi_req(rsp)->resid_len -= 8;
break; break;
} }
@ -348,13 +348,13 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
break; break;
case SMP_PHY_CONTROL: case SMP_PHY_CONTROL:
req->resid_len -= 44; scsi_req(req)->resid_len -= 44;
if ((int)req->resid_len < 0) { if ((int)scsi_req(req)->resid_len < 0) {
req->resid_len = 0; scsi_req(req)->resid_len = 0;
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
rsp->resid_len -= 8; scsi_req(rsp)->resid_len -= 8;
sas_phy_control(sas_ha, req_data[9], req_data[10], sas_phy_control(sas_ha, req_data[9], req_data[10],
req_data[32] >> 4, req_data[33] >> 4, req_data[32] >> 4, req_data[33] >> 4,
resp_data); resp_data);

Просмотреть файл

@ -2057,10 +2057,10 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
ioc->name, __func__, ioc->name, __func__,
le16_to_cpu(mpi_reply->ResponseDataLength))); le16_to_cpu(mpi_reply->ResponseDataLength)));
memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); memcpy(scsi_req(req)->sense, mpi_reply, sizeof(*mpi_reply));
req->sense_len = sizeof(*mpi_reply); scsi_req(req)->sense_len = sizeof(*mpi_reply);
req->resid_len = 0; scsi_req(req)->resid_len = 0;
rsp->resid_len -= scsi_req(rsp)->resid_len -=
le16_to_cpu(mpi_reply->ResponseDataLength); le16_to_cpu(mpi_reply->ResponseDataLength);
/* check if the resp needs to be copied from the allocated /* check if the resp needs to be copied from the allocated

Просмотреть файл

@ -48,6 +48,7 @@
#include <scsi/osd_sense.h> #include <scsi/osd_sense.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_request.h>
#include "osd_debug.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->async_error = error;
or->req_errors = req->errors ? : 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) 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) 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) 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); req = blk_get_request(q, has_write ? WRITE : READ, flags);
if (IS_ERR(req)) if (IS_ERR(req))
return req; return req;
blk_rq_set_block_pc(req); scsi_req_init(req);
for_each_bio(bio) { for_each_bio(bio) {
struct bio *bounce_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->timeout = or->timeout;
req->retries = or->retries; req->retries = or->retries;
req->sense = or->sense;
req->sense_len = 0;
if (has_out) { if (has_out) {
or->out.req = req; or->out.req = req;
@ -1612,7 +1613,7 @@ static int _init_blk_request(struct osd_request *or,
ret = PTR_ERR(req); ret = PTR_ERR(req);
goto out; goto out;
} }
blk_rq_set_block_pc(req); scsi_req_init(req);
or->in.req = or->request->next_rq = req; or->in.req = or->request->next_rq = req;
} }
} else if (has_in) } else if (has_in)
@ -1699,8 +1700,8 @@ int osd_finalize_request(struct osd_request *or,
osd_sec_sign_cdb(&or->cdb, cap_key); osd_sec_sign_cdb(&or->cdb, cap_key);
or->request->cmd = or->cdb.buff; scsi_req(or->request)->cmd = or->cdb.buff;
or->request->cmd_len = _osd_req_cdb_len(or); scsi_req(or->request)->cmd_len = _osd_req_cdb_len(or);
return 0; return 0;
} }

Просмотреть файл

@ -322,6 +322,7 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
/* Wakeup from interrupt */ /* Wakeup from interrupt */
static void osst_end_async(struct request *req, int update) 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_request *SRpnt = req->end_io_data;
struct osst_tape *STp = SRpnt->stp; struct osst_tape *STp = SRpnt->stp;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 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 #if DEBUG
STp->write_pending = 0; STp->write_pending = 0;
#endif #endif
if (rq->sense_len)
memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
if (SRpnt->waiting) if (SRpnt->waiting)
complete(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) int use_sg, int timeout, int retries)
{ {
struct request *req; struct request *req;
struct scsi_request *rq;
struct page **pages = NULL; struct page **pages = NULL;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 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)) if (IS_ERR(req))
return DRIVER_ERROR << 24; return DRIVER_ERROR << 24;
blk_rq_set_block_pc(req); rq = scsi_req(req);
scsi_req_init(req);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
SRpnt->bio = NULL; SRpnt->bio = NULL;
@ -404,11 +409,9 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
goto free_req; goto free_req;
} }
req->cmd_len = cmd_len; rq->cmd_len = cmd_len;
memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
memcpy(req->cmd, cmd, req->cmd_len); memcpy(rq->cmd, cmd, rq->cmd_len);
req->sense = SRpnt->sense;
req->sense_len = 0;
req->timeout = timeout; req->timeout = timeout;
req->retries = retries; req->retries = retries;
req->end_io_data = SRpnt; req->end_io_data = SRpnt;

Просмотреть файл

@ -921,7 +921,7 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
bsg_job->reply_len = sizeof(struct fc_bsg_reply) + bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
sizeof(response) + sizeof(uint8_t); 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); sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, response, sizeof(response)); memcpy(fw_sts_ptr, response, sizeof(response));
fw_sts_ptr += sizeof(response); fw_sts_ptr += sizeof(response);

Просмотреть файл

@ -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], type, sp->handle, comp_status, fw_status[1], fw_status[2],
le16_to_cpu(((struct els_sts_entry_24xx *) le16_to_cpu(((struct els_sts_entry_24xx *)
pkt)->total_byte_count)); 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)); memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
} }
else { else {
@ -1482,7 +1483,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
pkt)->error_subcode_2)); pkt)->error_subcode_2));
res = DID_ERROR << 16; res = DID_ERROR << 16;
bsg_reply->reply_payload_rcv_len = 0; 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)); memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
} }
ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056,

Просмотреть файл

@ -2244,7 +2244,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
memcpy(fstatus.reserved_3, memcpy(fstatus.reserved_3,
pkt->reserved_2, 20 * sizeof(uint8_t)); 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); sizeof(struct fc_bsg_reply);
memcpy(fw_sts_ptr, (uint8_t *)&fstatus, memcpy(fw_sts_ptr, (uint8_t *)&fstatus,

Просмотреть файл

@ -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) static void scsi_eh_lock_door(struct scsi_device *sdev)
{ {
struct request *req; struct request *req;
struct scsi_request *rq;
/* /*
* blk_get_request with GFP_KERNEL (__GFP_RECLAIM) sleeps until a * 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); req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
if (IS_ERR(req)) if (IS_ERR(req))
return; return;
rq = scsi_req(req);
scsi_req_init(req);
blk_rq_set_block_pc(req); rq->cmd[0] = ALLOW_MEDIUM_REMOVAL;
rq->cmd[1] = 0;
req->cmd[0] = ALLOW_MEDIUM_REMOVAL; rq->cmd[2] = 0;
req->cmd[1] = 0; rq->cmd[3] = 0;
req->cmd[2] = 0; rq->cmd[4] = SCSI_REMOVAL_PREVENT;
req->cmd[3] = 0; rq->cmd[5] = 0;
req->cmd[4] = SCSI_REMOVAL_PREVENT; rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
req->cmd[5] = 0;
req->cmd_len = COMMAND_SIZE(req->cmd[0]);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
req->timeout = 10 * HZ; req->timeout = 10 * HZ;
@ -2355,7 +2355,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
scmd = (struct scsi_cmnd *)(rq + 1); scmd = (struct scsi_cmnd *)(rq + 1);
scsi_init_command(dev, scmd); scsi_init_command(dev, scmd);
scmd->request = rq; scmd->request = rq;
scmd->cmnd = rq->cmd; scmd->cmnd = scsi_req(rq)->cmd;
scmd->scsi_done = scsi_reset_provider_done_command; scmd->scsi_done = scsi_reset_provider_done_command;
memset(&scmd->sdb, 0, sizeof(scmd->sdb)); memset(&scmd->sdb, 0, sizeof(scmd->sdb));

Просмотреть файл

@ -220,21 +220,21 @@ static int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
{ {
struct request *req; struct request *req;
int write = (data_direction == DMA_TO_DEVICE); int write = (data_direction == DMA_TO_DEVICE);
struct scsi_request *rq;
int ret = DRIVER_ERROR << 24; int ret = DRIVER_ERROR << 24;
req = blk_get_request(sdev->request_queue, write, __GFP_RECLAIM); req = blk_get_request(sdev->request_queue, write, __GFP_RECLAIM);
if (IS_ERR(req)) if (IS_ERR(req))
return ret; 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, if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
buffer, bufflen, __GFP_RECLAIM)) buffer, bufflen, __GFP_RECLAIM))
goto out; goto out;
req->cmd_len = COMMAND_SIZE(cmd[0]); rq->cmd_len = COMMAND_SIZE(cmd[0]);
memcpy(req->cmd, cmd, req->cmd_len); memcpy(rq->cmd, cmd, rq->cmd_len);
req->sense = sense;
req->sense_len = 0;
req->retries = retries; req->retries = retries;
req->timeout = timeout; req->timeout = timeout;
req->cmd_flags |= flags; 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 * is invalid. Prevent the garbage from being misinterpreted
* and prevent security leaks by zeroing out the excess data. * and prevent security leaks by zeroing out the excess data.
*/ */
if (unlikely(req->resid_len > 0 && req->resid_len <= bufflen)) if (unlikely(rq->resid_len > 0 && rq->resid_len <= bufflen))
memset(buffer + (bufflen - req->resid_len), 0, req->resid_len); memset(buffer + (bufflen - rq->resid_len), 0, rq->resid_len);
if (resid) 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; ret = req->errors;
out: out:
blk_put_request(req); 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 (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */
if (result) { if (result) {
if (sense_valid && req->sense) { if (sense_valid) {
/* /*
* SG_IO wants current and deferred errors * SG_IO wants current and deferred errors
*/ */
int len = 8 + cmd->sense_buffer[7]; scsi_req(req)->sense_len =
min(8 + cmd->sense_buffer[7],
if (len > SCSI_SENSE_BUFFERSIZE) SCSI_SENSE_BUFFERSIZE);
len = SCSI_SENSE_BUFFERSIZE;
memcpy(req->sense, cmd->sense_buffer, len);
req->sense_len = len;
} }
if (!sense_deferred) if (!sense_deferred)
error = __scsi_error_from_host_byte(cmd, result); 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->errors = cmd->result;
req->resid_len = scsi_get_resid(cmd); scsi_req(req)->resid_len = scsi_get_resid(cmd);
if (scsi_bidi_cmnd(cmd)) { if (scsi_bidi_cmnd(cmd)) {
/* /*
* Bidi commands Must be complete as a whole, * Bidi commands Must be complete as a whole,
* both sides at once. * 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), if (scsi_end_request(req, 0, blk_rq_bytes(req),
blk_rq_bytes(req->next_rq))) blk_rq_bytes(req->next_rq)))
BUG(); BUG();
@ -1165,7 +1164,10 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd)
void *prot = cmd->prot_sdb; void *prot = cmd->prot_sdb;
unsigned long flags; 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->device = dev;
cmd->sense_buffer = buf; cmd->sense_buffer = buf;
cmd->prot_sdb = prot; 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)); 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->transfersize = blk_rq_bytes(req);
cmd->allowed = req->retries; cmd->allowed = req->retries;
return BLKPREP_OK; return BLKPREP_OK;
@ -1217,6 +1220,7 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
return ret; return ret;
} }
cmd->cmnd = scsi_req(req)->cmd = scsi_req(req)->__cmd;
memset(cmd->cmnd, 0, BLK_MAX_CDB); memset(cmd->cmnd, 0, BLK_MAX_CDB);
return scsi_cmd_to_driver(cmd)->init_command(cmd); 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->tag = req->tag;
cmd->request = req; cmd->request = req;
cmd->cmnd = req->cmd;
cmd->prot_op = SCSI_PROT_NORMAL; cmd->prot_op = SCSI_PROT_NORMAL;
ret = scsi_setup_cmnd(sdev, req); 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; unsigned char *sense_buf = cmd->sense_buffer;
struct scatterlist *sg; 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; req->special = cmd;
@ -1884,7 +1889,6 @@ static int scsi_mq_prep_fn(struct request *req)
cmd->tag = req->tag; cmd->tag = req->tag;
cmd->cmnd = req->cmd;
cmd->prot_op = SCSI_PROT_NORMAL; cmd->prot_op = SCSI_PROT_NORMAL;
INIT_LIST_HEAD(&cmd->list); 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)) if (!scsi_host_queue_ready(q, shost, sdev))
goto out_dec_target_busy; goto out_dec_target_busy;
if (!(req->rq_flags & RQF_DONTPREP)) { if (!(req->rq_flags & RQF_DONTPREP)) {
ret = prep_to_mq(scsi_mq_prep_fn(req)); ret = prep_to_mq(scsi_mq_prep_fn(req));
if (ret != BLK_MQ_RQ_QUEUE_OK) 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); scsi_alloc_sense_buffer(shost, GFP_KERNEL, numa_node);
if (!cmd->sense_buffer) if (!cmd->sense_buffer)
return -ENOMEM; return -ENOMEM;
cmd->req.sense = cmd->sense_buffer;
return 0; 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); cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp, NUMA_NO_NODE);
if (!cmd->sense_buffer) if (!cmd->sense_buffer)
goto fail; goto fail;
cmd->req.sense = cmd->sense_buffer;
if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp); cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp);

Просмотреть файл

@ -33,6 +33,7 @@
#include <linux/bsg.h> #include <linux/bsg.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_request.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_transport.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) { while ((req = blk_fetch_request(q)) != NULL) {
spin_unlock_irq(q->queue_lock); 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; handler = to_sas_internal(shost->transportt)->f->smp_handler;
ret = handler(shost, rphy, req); ret = handler(shost, rphy, req);
req->errors = ret; req->errors = ret;

Просмотреть файл

@ -781,7 +781,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
rq->special_vec.bv_len = len; rq->special_vec.bv_len = len;
rq->rq_flags |= RQF_SPECIAL_PAYLOAD; rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
rq->resid_len = len; scsi_req(rq)->resid_len = len;
ret = scsi_init_io(cmd); ret = scsi_init_io(cmd);
out: out:
@ -1164,7 +1164,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
__free_page(rq->special_vec.bv_page); __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); mempool_free(SCpnt->cmnd, sd_cdb_pool);
SCpnt->cmnd = NULL; SCpnt->cmnd = NULL;
SCpnt->cmd_len = 0; SCpnt->cmd_len = 0;

Просмотреть файл

@ -781,9 +781,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
} }
if (atomic_read(&sdp->detaching)) { if (atomic_read(&sdp->detaching)) {
if (srp->bio) { if (srp->bio) {
if (srp->rq->cmd != srp->rq->__cmd) scsi_req_free_cmd(scsi_req(srp->rq));
kfree(srp->rq->cmd);
blk_end_request_all(srp->rq, -EIO); blk_end_request_all(srp->rq, -EIO);
srp->rq = NULL; srp->rq = NULL;
} }
@ -1279,6 +1277,7 @@ static void
sg_rq_end_io(struct request *rq, int uptodate) sg_rq_end_io(struct request *rq, int uptodate)
{ {
struct sg_request *srp = rq->end_io_data; struct sg_request *srp = rq->end_io_data;
struct scsi_request *req = scsi_req(rq);
Sg_device *sdp; Sg_device *sdp;
Sg_fd *sfp; Sg_fd *sfp;
unsigned long iflags; unsigned long iflags;
@ -1297,9 +1296,9 @@ sg_rq_end_io(struct request *rq, int uptodate)
if (unlikely(atomic_read(&sdp->detaching))) if (unlikely(atomic_read(&sdp->detaching)))
pr_info("%s: device detaching\n", __func__); pr_info("%s: device detaching\n", __func__);
sense = rq->sense; sense = req->sense;
result = rq->errors; result = rq->errors;
resid = rq->resid_len; resid = req->resid_len;
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp, SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp,
"sg_cmd_done: pack_id=%d, res=0x%x\n", "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; 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" */ /* 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. * blk_rq_unmap_user() can be called from user context.
*/ */
srp->rq = NULL; srp->rq = NULL;
if (rq->cmd != rq->__cmd) scsi_req_free_cmd(scsi_req(rq));
kfree(rq->cmd);
__blk_put_request(rq->q, rq); __blk_put_request(rq->q, rq);
write_lock_irqsave(&sfp->rq_list_lock, iflags); write_lock_irqsave(&sfp->rq_list_lock, iflags);
@ -1658,6 +1660,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
{ {
int res; int res;
struct request *rq; struct request *rq;
struct scsi_request *req;
Sg_fd *sfp = srp->parentfp; Sg_fd *sfp = srp->parentfp;
sg_io_hdr_t *hp = &srp->header; sg_io_hdr_t *hp = &srp->header;
int dxfer_len = (int) hp->dxfer_len; int dxfer_len = (int) hp->dxfer_len;
@ -1700,17 +1703,17 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
kfree(long_cmdp); kfree(long_cmdp);
return PTR_ERR(rq); 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) if (hp->cmd_len > BLK_MAX_CDB)
rq->cmd = long_cmdp; req->cmd = long_cmdp;
memcpy(rq->cmd, cmd, hp->cmd_len); memcpy(req->cmd, cmd, hp->cmd_len);
rq->cmd_len = hp->cmd_len; req->cmd_len = hp->cmd_len;
srp->rq = rq; srp->rq = rq;
rq->end_io_data = srp; rq->end_io_data = srp;
rq->sense = srp->sense_b;
rq->retries = SG_DEFAULT_RETRIES; rq->retries = SG_DEFAULT_RETRIES;
if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE)) 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); ret = blk_rq_unmap_user(srp->bio);
if (srp->rq) { if (srp->rq) {
if (srp->rq->cmd != srp->rq->__cmd) scsi_req_free_cmd(scsi_req(srp->rq));
kfree(srp->rq->cmd);
blk_put_request(srp->rq); blk_put_request(srp->rq);
} }

Просмотреть файл

@ -475,7 +475,7 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req)
ktime_t now; ktime_t now;
now = ktime_get(); 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); 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_write_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_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 } else
atomic64_add(atomic_read(&STp->stats->last_write_size), atomic64_add(atomic_read(&STp->stats->last_write_size),
&STp->stats->write_byte_cnt); &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); 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_read_time);
atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_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) static void st_scsi_execute_end(struct request *req, int uptodate)
{ {
struct st_request *SRpnt = req->end_io_data; struct st_request *SRpnt = req->end_io_data;
struct scsi_request *rq = scsi_req(req);
struct scsi_tape *STp = SRpnt->stp; struct scsi_tape *STp = SRpnt->stp;
struct bio *tmp; struct bio *tmp;
STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 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); st_do_stats(STp, req);
tmp = SRpnt->bio; tmp = SRpnt->bio;
if (rq->sense_len)
memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
if (SRpnt->waiting) if (SRpnt->waiting)
complete(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) int timeout, int retries)
{ {
struct request *req; struct request *req;
struct scsi_request *rq;
struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
int err = 0; int err = 0;
int write = (data_direction == DMA_TO_DEVICE); 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); GFP_KERNEL);
if (IS_ERR(req)) if (IS_ERR(req))
return DRIVER_ERROR << 24; return DRIVER_ERROR << 24;
rq = scsi_req(req);
blk_rq_set_block_pc(req); scsi_req_init(req);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
mdata->null_mapped = 1; 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; SRpnt->bio = req->bio;
req->cmd_len = COMMAND_SIZE(cmd[0]); rq->cmd_len = COMMAND_SIZE(cmd[0]);
memset(req->cmd, 0, BLK_MAX_CDB); memset(rq->cmd, 0, BLK_MAX_CDB);
memcpy(req->cmd, cmd, req->cmd_len); memcpy(rq->cmd, cmd, rq->cmd_len);
req->sense = SRpnt->sense;
req->sense_len = 0;
req->timeout = timeout; req->timeout = timeout;
req->retries = retries; req->retries = retries;
req->end_io_data = SRpnt; req->end_io_data = SRpnt;

Просмотреть файл

@ -1013,7 +1013,7 @@ pscsi_execute_cmd(struct se_cmd *cmd)
goto fail; goto fail;
} }
blk_rq_set_block_pc(req); scsi_req_init(req);
if (sgl) { if (sgl) {
ret = pscsi_map_sg(cmd, sgl, sgl_nents, req); ret = pscsi_map_sg(cmd, sgl, sgl_nents, req);
@ -1023,10 +1023,8 @@ pscsi_execute_cmd(struct se_cmd *cmd)
req->end_io = pscsi_req_done; req->end_io = pscsi_req_done;
req->end_io_data = cmd; req->end_io_data = cmd;
req->cmd_len = scsi_command_size(pt->pscsi_cdb); scsi_req(req)->cmd_len = scsi_command_size(pt->pscsi_cdb);
req->cmd = &pt->pscsi_cdb[0]; scsi_req(req)->cmd = &pt->pscsi_cdb[0];
req->sense = &pt->pscsi_sense[0];
req->sense_len = 0;
if (pdv->pdv_sd->type == TYPE_DISK) if (pdv->pdv_sd->type == TYPE_DISK)
req->timeout = PS_TIMEOUT_DISK; req->timeout = PS_TIMEOUT_DISK;
else else
@ -1075,7 +1073,7 @@ static void pscsi_req_done(struct request *req, int uptodate)
struct pscsi_plugin_task *pt = cmd->priv; struct pscsi_plugin_task *pt = cmd->priv;
pt->pscsi_result = req->errors; pt->pscsi_result = req->errors;
pt->pscsi_resid = req->resid_len; pt->pscsi_resid = scsi_req(req)->resid_len;
cmd->scsi_status = status_byte(pt->pscsi_result) << 1; cmd->scsi_status = status_byte(pt->pscsi_result) << 1;
if (cmd->scsi_status) { if (cmd->scsi_status) {
@ -1096,6 +1094,7 @@ static void pscsi_req_done(struct request *req, int uptodate)
break; break;
} }
memcpy(pt->pscsi_sense, scsi_req(req)->sense, TRANSPORT_SENSE_BUFFER);
__blk_put_request(req->q, req); __blk_put_request(req->q, req);
kfree(pt); kfree(pt);
} }

Просмотреть файл

@ -10,6 +10,7 @@
#include <linux/nfsd/debug.h> #include <linux/nfsd/debug.h>
#include <scsi/scsi_proto.h> #include <scsi/scsi_proto.h>
#include <scsi/scsi_common.h> #include <scsi/scsi_common.h>
#include <scsi/scsi_request.h>
#include "blocklayoutxdr.h" #include "blocklayoutxdr.h"
#include "pnfs.h" #include "pnfs.h"
@ -213,6 +214,7 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
{ {
struct request_queue *q = bdev->bd_disk->queue; struct request_queue *q = bdev->bd_disk->queue;
struct request *rq; struct request *rq;
struct scsi_request *req;
size_t bufflen = 252, len, id_len; size_t bufflen = 252, len, id_len;
u8 *buf, *d, type, assoc; u8 *buf, *d, type, assoc;
int error; int error;
@ -226,18 +228,19 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
error = -ENOMEM; error = -ENOMEM;
goto out_free_buf; goto out_free_buf;
} }
blk_rq_set_block_pc(rq); req = scsi_req(rq);
scsi_req_init(rq);
error = blk_rq_map_kern(q, rq, buf, bufflen, GFP_KERNEL); error = blk_rq_map_kern(q, rq, buf, bufflen, GFP_KERNEL);
if (error) if (error)
goto out_put_request; goto out_put_request;
rq->cmd[0] = INQUIRY; req->cmd[0] = INQUIRY;
rq->cmd[1] = 1; req->cmd[1] = 1;
rq->cmd[2] = 0x83; req->cmd[2] = 0x83;
rq->cmd[3] = bufflen >> 8; req->cmd[3] = bufflen >> 8;
rq->cmd[4] = bufflen & 0xff; req->cmd[4] = bufflen & 0xff;
rq->cmd_len = COMMAND_SIZE(INQUIRY); req->cmd_len = COMMAND_SIZE(INQUIRY);
error = blk_execute_rq(rq->q, NULL, rq, 1); error = blk_execute_rq(rq->q, NULL, rq, 1);
if (error) { if (error) {

Просмотреть файл

@ -128,8 +128,6 @@ typedef __u32 __bitwise req_flags_t;
#define RQF_NOMERGE_FLAGS \ #define RQF_NOMERGE_FLAGS \
(RQF_STARTED | RQF_SOFTBARRIER | RQF_FLUSH_SEQ | RQF_SPECIAL_PAYLOAD) (RQF_STARTED | RQF_SOFTBARRIER | RQF_FLUSH_SEQ | RQF_SPECIAL_PAYLOAD)
#define BLK_MAX_CDB 16
/* /*
* Try to put the fields that are referenced together in the same cacheline. * Try to put the fields that are referenced together in the same cacheline.
* *
@ -227,17 +225,7 @@ struct request {
int errors; 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 extra_len; /* length of alignment and padding */
unsigned int sense_len;
unsigned int resid_len; /* residual count */
void *sense;
unsigned long deadline; unsigned long deadline;
struct list_head timeout_list; struct list_head timeout_list;
@ -925,7 +913,6 @@ extern void blk_rq_init(struct request_queue *q, struct request *rq);
extern void blk_put_request(struct request *); extern void blk_put_request(struct request *);
extern void __blk_put_request(struct request_queue *, struct request *); 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_get_request(struct request_queue *, int, gfp_t);
extern void blk_rq_set_block_pc(struct request *);
extern void blk_requeue_request(struct request_queue *, struct request *); extern void blk_requeue_request(struct request_queue *, struct request *);
extern int blk_lld_busy(struct request_queue *q); extern int blk_lld_busy(struct request_queue *q);
extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src, extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,

Просмотреть файл

@ -20,6 +20,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
/* for request_sense */ /* for request_sense */
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <scsi/scsi_cmnd.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/io.h> #include <asm/io.h>
@ -52,6 +53,11 @@ enum ata_cmd_type_bits {
((rq)->cmd_type == REQ_TYPE_ATA_PM_SUSPEND || \ ((rq)->cmd_type == REQ_TYPE_ATA_PM_SUSPEND || \
(rq)->cmd_type == REQ_TYPE_ATA_PM_RESUME) (rq)->cmd_type == REQ_TYPE_ATA_PM_RESUME)
struct ide_request {
struct scsi_request sreq;
u8 sense[SCSI_SENSE_BUFFERSIZE];
};
/* Error codes returned in rq->errors to the higher part of the driver. */ /* Error codes returned in rq->errors to the higher part of the driver. */
enum { enum {
IDE_DRV_ERROR_GENERAL = 101, IDE_DRV_ERROR_GENERAL = 101,
@ -579,7 +585,7 @@ struct ide_drive_s {
/* current sense rq and buffer */ /* current sense rq and buffer */
bool sense_rq_armed; bool sense_rq_armed;
struct request sense_rq; struct request *sense_rq;
struct request_sense sense_data; struct request_sense sense_data;
}; };

Просмотреть файл

@ -8,6 +8,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_request.h>
struct Scsi_Host; struct Scsi_Host;
struct scsi_driver; struct scsi_driver;
@ -57,6 +58,7 @@ struct scsi_pointer {
#define SCMD_TAGGED (1 << 0) #define SCMD_TAGGED (1 << 0)
struct scsi_cmnd { struct scsi_cmnd {
struct scsi_request req;
struct scsi_device *device; struct scsi_device *device;
struct list_head list; /* scsi_cmnd participates in queue lists */ struct list_head list; /* scsi_cmnd participates in queue lists */
struct list_head eh_entry; /* entry for the host eh_cmd_q */ struct list_head eh_entry; /* entry for the host eh_cmd_q */

Просмотреть файл

@ -0,0 +1,30 @@
#ifndef _SCSI_SCSI_REQUEST_H
#define _SCSI_SCSI_REQUEST_H
#include <linux/blk-mq.h>
#define BLK_MAX_CDB 16
struct scsi_request {
unsigned char __cmd[BLK_MAX_CDB];
unsigned char *cmd;
unsigned short cmd_len;
unsigned int sense_len;
unsigned int resid_len; /* residual count */
void *sense;
};
static inline struct scsi_request *scsi_req(struct request *rq)
{
return blk_mq_rq_to_pdu(rq);
}
static inline void scsi_req_free_cmd(struct scsi_request *req)
{
if (req->cmd != req->__cmd)
kfree(req->cmd);
}
void scsi_req_init(struct request *);
#endif /* _SCSI_SCSI_REQUEST_H */