You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
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:
committed by
Jens Axboe
parent
8ae94eb65b
commit
82ed4db499
@@ -132,8 +132,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
|
||||
rq->__sector = (sector_t) -1;
|
||||
INIT_HLIST_NODE(&rq->hash);
|
||||
RB_CLEAR_NODE(&rq->rb_node);
|
||||
rq->cmd = rq->__cmd;
|
||||
rq->cmd_len = BLK_MAX_CDB;
|
||||
rq->tag = -1;
|
||||
rq->internal_tag = -1;
|
||||
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)
|
||||
{
|
||||
int bit;
|
||||
|
||||
printk(KERN_INFO "%s: dev %s: type=%x, flags=%llx\n", msg,
|
||||
rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
|
||||
(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));
|
||||
printk(KERN_INFO " bio %p, biotail %p, len %u\n",
|
||||
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);
|
||||
|
||||
@@ -1315,18 +1304,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
|
||||
}
|
||||
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
|
||||
* @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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
blk_add_timer(req);
|
||||
}
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
#include "blk.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
|
||||
* @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)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(wait);
|
||||
char sense[SCSI_SENSE_BUFFERSIZE];
|
||||
int err = 0;
|
||||
unsigned long hang_check;
|
||||
|
||||
if (!rq->sense) {
|
||||
memset(sense, 0, sizeof(sense));
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
}
|
||||
|
||||
rq->end_io_data = &wait;
|
||||
blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
|
||||
|
||||
@@ -124,11 +112,6 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
|
||||
if (rq->errors)
|
||||
err = -EIO;
|
||||
|
||||
if (rq->sense == sense) {
|
||||
rq->sense = NULL;
|
||||
rq->sense_len = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_execute_rq);
|
||||
|
||||
@@ -199,13 +199,7 @@ void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
|
||||
rq->special = NULL;
|
||||
/* tag was already set */
|
||||
rq->errors = 0;
|
||||
|
||||
rq->cmd = rq->__cmd;
|
||||
|
||||
rq->extra_len = 0;
|
||||
rq->sense_len = 0;
|
||||
rq->resid_len = 0;
|
||||
rq->sense = NULL;
|
||||
|
||||
INIT_LIST_HEAD(&rq->timeout_list);
|
||||
rq->timeout = 0;
|
||||
@@ -487,10 +481,6 @@ void blk_mq_start_request(struct request *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)) {
|
||||
blk_stat_set_issue_time(&rq->issue_stat);
|
||||
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 *rsp = req->next_rq;
|
||||
struct scsi_request *rq = scsi_req(req);
|
||||
int err;
|
||||
|
||||
err = job->req->errors = result;
|
||||
if (err < 0)
|
||||
/* we're only returning the result field in the reply */
|
||||
job->req->sense_len = sizeof(u32);
|
||||
rq->sense_len = sizeof(u32);
|
||||
else
|
||||
job->req->sense_len = job->reply_len;
|
||||
rq->sense_len = job->reply_len;
|
||||
/* we assume all request payload was transferred, residual == 0 */
|
||||
req->resid_len = 0;
|
||||
rq->resid_len = 0;
|
||||
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
@@ -113,6 +115,7 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
|
||||
if (!buf->sg_list)
|
||||
return -ENOMEM;
|
||||
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->payload_len = blk_rq_bytes(req);
|
||||
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_queue *q = req->q;
|
||||
struct scsi_request *rq = scsi_req(req);
|
||||
struct bsg_job *job;
|
||||
int ret;
|
||||
|
||||
@@ -140,9 +144,9 @@ static int bsg_create_job(struct device *dev, struct request *req)
|
||||
job->req = req;
|
||||
if (q->bsg_job_size)
|
||||
job->dd_data = (void *)&job[1];
|
||||
job->request = req->cmd;
|
||||
job->request_len = req->cmd_len;
|
||||
job->reply = req->sense;
|
||||
job->request = rq->cmd;
|
||||
job->request_len = rq->cmd_len;
|
||||
job->reply = rq->sense;
|
||||
job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
|
||||
* allocated */
|
||||
if (req->bio) {
|
||||
@@ -228,9 +232,15 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
|
||||
struct request_queue *q;
|
||||
int ret;
|
||||
|
||||
q = blk_init_queue(bsg_request_fn, NULL);
|
||||
q = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!q)
|
||||
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->bsg_job_size = dd_job_size;
|
||||
@@ -243,10 +253,12 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: bsg interface failed to "
|
||||
"initialize - register queue\n", dev->kobj.name);
|
||||
blk_cleanup_queue(q);
|
||||
return ERR_PTR(ret);
|
||||
goto out_cleanup_queue;
|
||||
}
|
||||
|
||||
return q;
|
||||
out_cleanup_queue:
|
||||
blk_cleanup_queue(q);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bsg_setup_queue);
|
||||
|
||||
47
block/bsg.c
47
block/bsg.c
@@ -85,7 +85,6 @@ struct bsg_command {
|
||||
struct bio *bidi_bio;
|
||||
int err;
|
||||
struct sg_io_v4 hdr;
|
||||
char sense[SCSI_SENSE_BUFFERSIZE];
|
||||
};
|
||||
|
||||
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,
|
||||
fmode_t has_write_perm)
|
||||
{
|
||||
struct scsi_request *req = scsi_req(rq);
|
||||
|
||||
if (hdr->request_len > BLK_MAX_CDB) {
|
||||
rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
|
||||
if (!rq->cmd)
|
||||
req->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
|
||||
if (!req->cmd)
|
||||
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))
|
||||
return -EFAULT;
|
||||
|
||||
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;
|
||||
} else if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
@@ -159,7 +160,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
|
||||
/*
|
||||
* fill in request structure
|
||||
*/
|
||||
rq->cmd_len = hdr->request_len;
|
||||
req->cmd_len = hdr->request_len;
|
||||
|
||||
rq->timeout = msecs_to_jiffies(hdr->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.
|
||||
*/
|
||||
static struct request *
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
|
||||
u8 *sense)
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
|
||||
{
|
||||
struct request_queue *q = bd->queue;
|
||||
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);
|
||||
if (IS_ERR(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);
|
||||
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;
|
||||
}
|
||||
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
|
||||
return rq;
|
||||
out:
|
||||
if (rq->cmd != rq->__cmd)
|
||||
kfree(rq->cmd);
|
||||
scsi_req_free_cmd(scsi_req(rq));
|
||||
blk_put_request(rq);
|
||||
if (next_rq) {
|
||||
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,
|
||||
struct bio *bio, struct bio *bidi_bio)
|
||||
{
|
||||
struct scsi_request *req = scsi_req(rq);
|
||||
int ret = 0;
|
||||
|
||||
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->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,
|
||||
rq->sense_len);
|
||||
req->sense_len);
|
||||
|
||||
ret = copy_to_user((void __user *)(unsigned long)hdr->response,
|
||||
rq->sense, len);
|
||||
req->sense, len);
|
||||
if (!ret)
|
||||
hdr->response_len = len;
|
||||
else
|
||||
@@ -420,14 +417,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
||||
}
|
||||
|
||||
if (rq->next_rq) {
|
||||
hdr->dout_resid = rq->resid_len;
|
||||
hdr->din_resid = rq->next_rq->resid_len;
|
||||
hdr->dout_resid = req->resid_len;
|
||||
hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
|
||||
blk_rq_unmap_user(bidi_bio);
|
||||
blk_put_request(rq->next_rq);
|
||||
} else if (rq_data_dir(rq) == READ)
|
||||
hdr->din_resid = rq->resid_len;
|
||||
hdr->din_resid = req->resid_len;
|
||||
else
|
||||
hdr->dout_resid = rq->resid_len;
|
||||
hdr->dout_resid = req->resid_len;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
blk_rq_unmap_user(bio);
|
||||
if (rq->cmd != rq->__cmd)
|
||||
kfree(rq->cmd);
|
||||
scsi_req_free_cmd(req);
|
||||
blk_put_request(rq);
|
||||
|
||||
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
|
||||
*/
|
||||
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)) {
|
||||
ret = PTR_ERR(rq);
|
||||
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 sg_io_v4 hdr;
|
||||
int at_head;
|
||||
u8 sense[SCSI_SENSE_BUFFERSIZE];
|
||||
|
||||
if (copy_from_user(&hdr, uarg, sizeof(hdr)))
|
||||
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))
|
||||
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,
|
||||
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;
|
||||
if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
|
||||
if (blk_verify_command(req->cmd, mode & FMODE_WRITE))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* fill in request structure
|
||||
*/
|
||||
rq->cmd_len = hdr->cmd_len;
|
||||
req->cmd_len = hdr->cmd_len;
|
||||
|
||||
rq->timeout = msecs_to_jiffies(hdr->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,
|
||||
struct bio *bio)
|
||||
{
|
||||
struct scsi_request *req = scsi_req(rq);
|
||||
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;
|
||||
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
|
||||
hdr->info |= SG_INFO_CHECK;
|
||||
hdr->resid = rq->resid_len;
|
||||
hdr->resid = req->resid_len;
|
||||
hdr->sb_len_wr = 0;
|
||||
|
||||
if (rq->sense_len && hdr->sbp) {
|
||||
int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
|
||||
if (req->sense_len && hdr->sbp) {
|
||||
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;
|
||||
else
|
||||
ret = -EFAULT;
|
||||
@@ -294,7 +297,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
|
||||
int writing = 0;
|
||||
int at_head = 0;
|
||||
struct request *rq;
|
||||
char sense[SCSI_SENSE_BUFFERSIZE];
|
||||
struct scsi_request *req;
|
||||
struct bio *bio;
|
||||
|
||||
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);
|
||||
if (IS_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) {
|
||||
rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
|
||||
if (!rq->cmd)
|
||||
req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
|
||||
if (!req->cmd)
|
||||
goto out_put_request;
|
||||
}
|
||||
|
||||
@@ -357,9 +361,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
|
||||
goto out_free_cdb;
|
||||
|
||||
bio = rq->bio;
|
||||
memset(sense, 0, sizeof(sense));
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
rq->retries = 0;
|
||||
|
||||
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);
|
||||
|
||||
out_free_cdb:
|
||||
if (rq->cmd != rq->__cmd)
|
||||
kfree(rq->cmd);
|
||||
scsi_req_free_cmd(req);
|
||||
out_put_request:
|
||||
blk_put_request(rq);
|
||||
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 request *rq;
|
||||
struct scsi_request *req;
|
||||
int err;
|
||||
unsigned int in_len, out_len, bytes, opcode, cmdlen;
|
||||
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
|
||||
char *buffer = NULL;
|
||||
|
||||
if (!sic)
|
||||
return -EINVAL;
|
||||
@@ -452,7 +453,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
|
||||
err = PTR_ERR(rq);
|
||||
goto error_free_buffer;
|
||||
}
|
||||
blk_rq_set_block_pc(rq);
|
||||
req = scsi_req(rq);
|
||||
scsi_req_init(rq);
|
||||
|
||||
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
|
||||
*/
|
||||
err = -EFAULT;
|
||||
rq->cmd_len = cmdlen;
|
||||
if (copy_from_user(rq->cmd, sic->data, cmdlen))
|
||||
req->cmd_len = cmdlen;
|
||||
if (copy_from_user(req->cmd, sic->data, cmdlen))
|
||||
goto error;
|
||||
|
||||
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
|
||||
goto error;
|
||||
|
||||
err = blk_verify_command(rq->cmd, mode & FMODE_WRITE);
|
||||
err = blk_verify_command(req->cmd, mode & FMODE_WRITE);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
@@ -503,18 +505,14 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(sense, 0, sizeof(sense));
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
|
||||
blk_execute_rq(q, disk, rq, 0);
|
||||
|
||||
err = rq->errors & 0xff; /* only 8 bit SCSI status */
|
||||
if (err) {
|
||||
if (rq->sense_len && rq->sense) {
|
||||
bytes = (OMAX_SB_LEN > rq->sense_len) ?
|
||||
rq->sense_len : OMAX_SB_LEN;
|
||||
if (copy_to_user(sic->data, rq->sense, bytes))
|
||||
if (req->sense_len && req->sense) {
|
||||
bytes = (OMAX_SB_LEN > req->sense_len) ?
|
||||
req->sense_len : OMAX_SB_LEN;
|
||||
if (copy_to_user(sic->data, req->sense, bytes))
|
||||
err = -EFAULT;
|
||||
}
|
||||
} 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);
|
||||
if (IS_ERR(rq))
|
||||
return PTR_ERR(rq);
|
||||
blk_rq_set_block_pc(rq);
|
||||
scsi_req_init(rq);
|
||||
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
|
||||
rq->cmd[0] = cmd;
|
||||
rq->cmd[4] = data;
|
||||
rq->cmd_len = 6;
|
||||
scsi_req(rq)->cmd[0] = cmd;
|
||||
scsi_req(rq)->cmd[4] = data;
|
||||
scsi_req(rq)->cmd_len = 6;
|
||||
err = blk_execute_rq(q, bd_disk, rq, 0);
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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)))
|
||||
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,
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/sg.h>
|
||||
#include <scsi/scsi_ioctl.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/kthread.h>
|
||||
@@ -1854,7 +1855,7 @@ static void cciss_softirq_done(struct request *rq)
|
||||
|
||||
/* set the residual count for pc requests */
|
||||
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);
|
||||
|
||||
@@ -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,
|
||||
int drv_index)
|
||||
{
|
||||
disk->queue = blk_init_queue(do_cciss_request, &h->lock);
|
||||
disk->queue = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!disk->queue)
|
||||
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);
|
||||
disk->major = h->major;
|
||||
disk->first_minor = drv_index << NWD_SHIFT;
|
||||
@@ -3111,15 +3119,7 @@ static inline int evaluate_target_status(ctlr_info_t *h,
|
||||
return error_value;
|
||||
}
|
||||
|
||||
/* SG_IO or similar, copy sense data back */
|
||||
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;
|
||||
|
||||
scsi_req(cmd->rq)->sense_len = cmd->err_info->SenseLen;
|
||||
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"
|
||||
" completed with data underrun "
|
||||
"reported\n", cmd);
|
||||
cmd->rq->resid_len = cmd->err_info->ResidualCnt;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
} else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) {
|
||||
c->Request.CDBLen = creq->cmd_len;
|
||||
memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
|
||||
c->Request.CDBLen = scsi_req(creq)->cmd_len;
|
||||
memcpy(c->Request.CDB, scsi_req(creq)->cmd, BLK_MAX_CDB);
|
||||
scsi_req(creq)->sense = c->err_info->SenseInfo;
|
||||
} else {
|
||||
dev_warn(&h->pdev->dev, "bad request type %d\n",
|
||||
creq->cmd_type);
|
||||
|
||||
@@ -707,7 +707,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
|
||||
WRITE : READ, __GFP_RECLAIM);
|
||||
if (IS_ERR(rq))
|
||||
return PTR_ERR(rq);
|
||||
blk_rq_set_block_pc(rq);
|
||||
scsi_req_init(rq);
|
||||
|
||||
if (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;
|
||||
}
|
||||
|
||||
rq->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
|
||||
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
|
||||
scsi_req(rq)->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
|
||||
memcpy(scsi_req(rq)->cmd, cgc->cmd, CDROM_PACKET_SIZE);
|
||||
|
||||
rq->timeout = 60*HZ;
|
||||
if (cgc->quiet)
|
||||
|
||||
@@ -52,6 +52,7 @@ struct virtio_blk {
|
||||
};
|
||||
|
||||
struct virtblk_req {
|
||||
struct scsi_request sreq; /* for SCSI passthrough */
|
||||
struct request *req;
|
||||
struct virtio_blk_outhdr out_hdr;
|
||||
struct virtio_scsi_inhdr in_hdr;
|
||||
@@ -91,7 +92,7 @@ static int __virtblk_add_req(struct virtqueue *vq,
|
||||
* inhdr with additional status information.
|
||||
*/
|
||||
if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
|
||||
sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len);
|
||||
sg_init_one(&cmd, vbr->sreq.cmd, vbr->sreq.cmd_len);
|
||||
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)) {
|
||||
memcpy(vbr->sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
|
||||
sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE);
|
||||
sgs[num_out + num_in++] = &sense;
|
||||
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);
|
||||
|
||||
if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
|
||||
req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
|
||||
req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
|
||||
scsi_req(req)->resid_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);
|
||||
} else if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
|
||||
req->errors = (error != 0);
|
||||
@@ -538,6 +540,7 @@ static int virtblk_init_request(void *data, struct request *rq,
|
||||
struct virtio_blk *vblk = data;
|
||||
struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
|
||||
|
||||
vbr->sreq.sense = vbr->sense;
|
||||
sg_init_table(vbr->sg, vblk->sg_elems);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -281,8 +281,8 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/times.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
|
||||
/* used to tell the module to turn on full debugging messages */
|
||||
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 *rq;
|
||||
struct scsi_request *req;
|
||||
struct bio *bio;
|
||||
unsigned int len;
|
||||
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);
|
||||
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);
|
||||
if (ret) {
|
||||
@@ -2203,23 +2205,23 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
|
||||
break;
|
||||
}
|
||||
|
||||
rq->cmd[0] = GPCMD_READ_CD;
|
||||
rq->cmd[1] = 1 << 2;
|
||||
rq->cmd[2] = (lba >> 24) & 0xff;
|
||||
rq->cmd[3] = (lba >> 16) & 0xff;
|
||||
rq->cmd[4] = (lba >> 8) & 0xff;
|
||||
rq->cmd[5] = lba & 0xff;
|
||||
rq->cmd[6] = (nr >> 16) & 0xff;
|
||||
rq->cmd[7] = (nr >> 8) & 0xff;
|
||||
rq->cmd[8] = nr & 0xff;
|
||||
rq->cmd[9] = 0xf8;
|
||||
req->cmd[0] = GPCMD_READ_CD;
|
||||
req->cmd[1] = 1 << 2;
|
||||
req->cmd[2] = (lba >> 24) & 0xff;
|
||||
req->cmd[3] = (lba >> 16) & 0xff;
|
||||
req->cmd[4] = (lba >> 8) & 0xff;
|
||||
req->cmd[5] = lba & 0xff;
|
||||
req->cmd[6] = (nr >> 16) & 0xff;
|
||||
req->cmd[7] = (nr >> 8) & 0xff;
|
||||
req->cmd[8] = nr & 0xff;
|
||||
req->cmd[9] = 0xf8;
|
||||
|
||||
rq->cmd_len = 12;
|
||||
req->cmd_len = 12;
|
||||
rq->timeout = 60 * HZ;
|
||||
bio = rq->bio;
|
||||
|
||||
if (blk_execute_rq(q, cdi->disk, rq, 0)) {
|
||||
struct request_sense *s = rq->sense;
|
||||
struct request_sense *s = req->sense;
|
||||
ret = -EIO;
|
||||
cdi->last_sense = s->sense_key;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
|
||||
int error;
|
||||
|
||||
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
|
||||
scsi_req_init(rq);
|
||||
rq->cmd_type = REQ_TYPE_DRV_PRIV;
|
||||
rq->special = (char *)pc;
|
||||
|
||||
@@ -103,9 +104,9 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
|
||||
goto put_req;
|
||||
}
|
||||
|
||||
memcpy(rq->cmd, pc->c, 12);
|
||||
memcpy(scsi_req(rq)->cmd, pc->c, 12);
|
||||
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);
|
||||
put_req:
|
||||
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)
|
||||
{
|
||||
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;
|
||||
int err;
|
||||
|
||||
@@ -197,6 +199,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
|
||||
memset(sense, 0, sizeof(*sense));
|
||||
|
||||
blk_rq_init(rq->q, sense_rq);
|
||||
scsi_req_init(sense_rq);
|
||||
|
||||
err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
|
||||
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->cmd[0] = GPCMD_REQUEST_SENSE;
|
||||
sense_rq->cmd[4] = cmd_len;
|
||||
sense_rq->cmd_type = REQ_TYPE_ATA_SENSE;
|
||||
sense_rq->rq_flags |= RQF_PREEMPT;
|
||||
|
||||
req->cmd[0] = GPCMD_REQUEST_SENSE;
|
||||
req->cmd[4] = cmd_len;
|
||||
if (drive->media == ide_tape)
|
||||
sense_rq->cmd[13] = REQ_IDETAPE_PC1;
|
||||
req->cmd[13] = REQ_IDETAPE_PC1;
|
||||
|
||||
drive->sense_rq_armed = true;
|
||||
}
|
||||
@@ -229,12 +232,12 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
drive->sense_rq.special = special;
|
||||
drive->sense_rq->special = special;
|
||||
drive->sense_rq_armed = false;
|
||||
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
(void)ide_read_error(drive);
|
||||
|
||||
/* init pc from sense_rq */
|
||||
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)
|
||||
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
|
||||
* for these.
|
||||
*/
|
||||
switch (rq->cmd[0]) {
|
||||
switch (scsi_req(rq)->cmd[0]) {
|
||||
case GPCMD_BLANK:
|
||||
case GPCMD_FORMAT_UNIT:
|
||||
case GPCMD_RESERVE_RZONE_TRACK:
|
||||
@@ -297,7 +300,7 @@ int ide_cd_expiry(ide_drive_t *drive)
|
||||
default:
|
||||
if (!(rq->rq_flags & RQF_QUIET))
|
||||
printk(KERN_INFO PFX "cmd 0x%x timed out\n",
|
||||
rq->cmd[0]);
|
||||
scsi_req(rq)->cmd[0]);
|
||||
wait = 0;
|
||||
break;
|
||||
}
|
||||
@@ -420,7 +423,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
|
||||
? "write" : "read");
|
||||
pc->flags |= PC_FLAG_DMA_ERROR;
|
||||
} else
|
||||
rq->resid_len = 0;
|
||||
scsi_req(rq)->resid_len = 0;
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
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 "
|
||||
"sense command\n", drive->name);
|
||||
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);
|
||||
|
||||
/* Update transferred byte count */
|
||||
rq->resid_len -= done;
|
||||
scsi_req(rq)->resid_len -= done;
|
||||
|
||||
bcount -= done;
|
||||
|
||||
@@ -520,7 +523,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
|
||||
ide_pad_transfer(drive, write, bcount);
|
||||
|
||||
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 */
|
||||
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)) {
|
||||
/* 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)
|
||||
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 */
|
||||
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 */
|
||||
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));
|
||||
|
||||
/* We haven't transferred any data yet */
|
||||
rq->resid_len = bcount;
|
||||
scsi_req(rq)->resid_len = bcount;
|
||||
|
||||
if (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
|
||||
* 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;
|
||||
log = 1;
|
||||
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
|
||||
* 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)
|
||||
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);
|
||||
|
||||
if (failed) {
|
||||
if (failed->sense) {
|
||||
/*
|
||||
* Sense is always read into drive->sense_data.
|
||||
* Copy back if the failed request has its
|
||||
* sense pointer set.
|
||||
*/
|
||||
memcpy(failed->sense, sense, 18);
|
||||
failed->sense_len = rq->sense_len;
|
||||
}
|
||||
/*
|
||||
* Sense is always read into drive->sense_data, copy back to the
|
||||
* original request.
|
||||
*/
|
||||
memcpy(scsi_req(failed)->sense, sense, 18);
|
||||
scsi_req(failed)->sense_len = scsi_req(rq)->sense_len;
|
||||
cdrom_analyze_sense_data(drive, 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!
|
||||
*/
|
||||
if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
|
||||
if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT)
|
||||
break;
|
||||
/* fall-through */
|
||||
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,
|
||||
* 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;
|
||||
}
|
||||
@@ -425,12 +422,8 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
|
||||
req_flags_t rq_flags)
|
||||
{
|
||||
struct cdrom_info *info = drive->driver_data;
|
||||
struct request_sense local_sense;
|
||||
int retries = 10;
|
||||
req_flags_t flags = 0;
|
||||
|
||||
if (!sense)
|
||||
sense = &local_sense;
|
||||
bool failed;
|
||||
|
||||
ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
|
||||
"rq_flags: 0x%x",
|
||||
@@ -440,12 +433,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
|
||||
do {
|
||||
struct request *rq;
|
||||
int error;
|
||||
bool delay = false;
|
||||
|
||||
rq = blk_get_request(drive->queue, write, __GFP_RECLAIM);
|
||||
|
||||
memcpy(rq->cmd, cmd, BLK_MAX_CDB);
|
||||
scsi_req_init(rq);
|
||||
memcpy(scsi_req(rq)->cmd, cmd, BLK_MAX_CDB);
|
||||
rq->cmd_type = REQ_TYPE_ATA_PC;
|
||||
rq->sense = sense;
|
||||
rq->rq_flags |= rq_flags;
|
||||
rq->timeout = timeout;
|
||||
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);
|
||||
|
||||
if (buffer)
|
||||
*bufflen = rq->resid_len;
|
||||
|
||||
flags = rq->rq_flags;
|
||||
blk_put_request(rq);
|
||||
*bufflen = scsi_req(rq)->resid_len;
|
||||
if (sense)
|
||||
memcpy(sense, scsi_req(rq)->sense, sizeof(*sense));
|
||||
|
||||
/*
|
||||
* FIXME: we should probably abort/retry or something in case of
|
||||
* 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
|
||||
* 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)
|
||||
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
|
||||
* the drive time to complete the load.
|
||||
*/
|
||||
ssleep(2);
|
||||
delay = true;
|
||||
} else {
|
||||
/* otherwise, don't retry */
|
||||
retries = 0;
|
||||
}
|
||||
--retries;
|
||||
}
|
||||
|
||||
/* end of retry loop */
|
||||
} while ((flags & RQF_FAILED) && retries >= 0);
|
||||
blk_put_request(rq);
|
||||
if (delay)
|
||||
ssleep(2);
|
||||
} while (failed && retries >= 0);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (sense && write == 0)
|
||||
rq->sense_len += blen;
|
||||
scsi_req(rq)->sense_len += blen;
|
||||
}
|
||||
|
||||
/* pad, if necessary */
|
||||
@@ -664,7 +658,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
|
||||
|
||||
out_end:
|
||||
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);
|
||||
hwif->rq = NULL;
|
||||
} else {
|
||||
@@ -685,9 +679,9 @@ out_end:
|
||||
|
||||
/* make sure it's fully ended */
|
||||
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))
|
||||
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));
|
||||
@@ -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);
|
||||
long block = (long)blk_rq_pos(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)
|
||||
rq->cmd[0] = GPCMD_READ_10;
|
||||
req->cmd[0] = GPCMD_READ_10;
|
||||
else
|
||||
rq->cmd[0] = GPCMD_WRITE_10;
|
||||
req->cmd[0] = GPCMD_WRITE_10;
|
||||
|
||||
/*
|
||||
* fill in lba
|
||||
*/
|
||||
rq->cmd[2] = (block >> 24) & 0xff;
|
||||
rq->cmd[3] = (block >> 16) & 0xff;
|
||||
rq->cmd[4] = (block >> 8) & 0xff;
|
||||
rq->cmd[5] = block & 0xff;
|
||||
req->cmd[2] = (block >> 24) & 0xff;
|
||||
req->cmd[3] = (block >> 16) & 0xff;
|
||||
req->cmd[4] = (block >> 8) & 0xff;
|
||||
req->cmd[5] = block & 0xff;
|
||||
|
||||
/*
|
||||
* and transfer length
|
||||
*/
|
||||
rq->cmd[7] = (blocks >> 8) & 0xff;
|
||||
rq->cmd[8] = blocks & 0xff;
|
||||
rq->cmd_len = 10;
|
||||
req->cmd[7] = (blocks >> 8) & 0xff;
|
||||
req->cmd[8] = blocks & 0xff;
|
||||
req->cmd_len = 10;
|
||||
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)
|
||||
{
|
||||
u8 *c = rq->cmd;
|
||||
u8 *c = scsi_req(rq)->cmd;
|
||||
|
||||
/* transform 6-byte read/write commands to the 10-byte version */
|
||||
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[1] &= 0xe0;
|
||||
c[0] += (READ_10 - READ_6);
|
||||
rq->cmd_len = 10;
|
||||
scsi_req(rq)->cmd_len = 10;
|
||||
return BLKPREP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -304,6 +304,7 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
|
||||
int ret;
|
||||
|
||||
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
|
||||
scsi_req_init(rq);
|
||||
rq->cmd_type = REQ_TYPE_DRV_PRIV;
|
||||
rq->rq_flags = RQF_QUIET;
|
||||
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) {
|
||||
mid = (lo + hi) / 2;
|
||||
if (packet_command_texts[mid].packet_command ==
|
||||
failed_command->cmd[0]) {
|
||||
scsi_req(failed_command)->cmd[0]) {
|
||||
s = packet_command_texts[mid].text;
|
||||
break;
|
||||
}
|
||||
if (packet_command_texts[mid].packet_command >
|
||||
failed_command->cmd[0])
|
||||
scsi_req(failed_command)->cmd[0])
|
||||
hi = mid;
|
||||
else
|
||||
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 "
|
||||
"was: \n \"", s);
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -166,10 +166,11 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
|
||||
return setting->set(drive, arg);
|
||||
|
||||
rq = blk_get_request(q, READ, __GFP_RECLAIM);
|
||||
scsi_req_init(rq);
|
||||
rq->cmd_type = REQ_TYPE_DRV_PRIV;
|
||||
rq->cmd_len = 5;
|
||||
rq->cmd[0] = REQ_DEVSET_EXEC;
|
||||
*(int *)&rq->cmd[1] = arg;
|
||||
scsi_req(rq)->cmd_len = 5;
|
||||
scsi_req(rq)->cmd[0] = REQ_DEVSET_EXEC;
|
||||
*(int *)&scsi_req(rq)->cmd[1] = arg;
|
||||
rq->special = setting->set;
|
||||
|
||||
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;
|
||||
|
||||
err = setfunc(drive, *(int *)&rq->cmd[1]);
|
||||
err = setfunc(drive, *(int *)&scsi_req(rq)->cmd[1]);
|
||||
if (err)
|
||||
rq->errors = err;
|
||||
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;
|
||||
|
||||
rq = blk_get_request(drive->queue, READ, __GFP_RECLAIM);
|
||||
scsi_req_init(rq);
|
||||
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
rq->errors = -EIO;
|
||||
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_be32(block), (unsigned int *) &pc->c[2]);
|
||||
|
||||
memcpy(rq->cmd, pc->c, 12);
|
||||
memcpy(scsi_req(rq)->cmd, pc->c, 12);
|
||||
|
||||
pc->rq = rq;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (blk_rq_bytes(rq)) {
|
||||
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)
|
||||
{
|
||||
u8 cmd = rq->cmd[0];
|
||||
u8 cmd = scsi_req(rq)->cmd[0];
|
||||
|
||||
switch (cmd) {
|
||||
case REQ_PARK_HEADS:
|
||||
@@ -545,6 +545,7 @@ repeat:
|
||||
goto plug_device;
|
||||
}
|
||||
|
||||
scsi_req(rq)->resid_len = blk_rq_bytes(rq);
|
||||
hwif->rq = rq;
|
||||
|
||||
spin_unlock_irq(&hwif->lock);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user