Commit 776b23a0 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[SCSI] always handle REQ_BLOCK_PC requests in common code

LLDDs should never see REQ_BLOCK_PC requests, we can handle them just
fine in the core code.  There is a small behaviour change in that some
check in sr's rw_intr are bypassed, but I consider the old behaviour
a bug.

Mike found this cleanup opportunity and provdided early patches, so all
the credit goes to him, even if I redid the patches from scratch beause
that was easier than forward-porting the old patches.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent d4054239
...@@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, ...@@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void scsi_generic_done(struct scsi_cmnd *cmd) static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
{ {
BUG_ON(!blk_pc_request(cmd->request)); BUG_ON(!blk_pc_request(cmd->request));
/* /*
...@@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) ...@@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd)
scsi_io_completion(cmd, cmd->bufflen, 0); scsi_io_completion(cmd, cmd->bufflen, 0);
} }
void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
{ {
struct request *req = cmd->request; struct request *req = cmd->request;
...@@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) ...@@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
cmd->transfersize = req->data_len; cmd->transfersize = req->data_len;
cmd->allowed = req->retries; cmd->allowed = req->retries;
cmd->timeout_per_command = req->timeout; cmd->timeout_per_command = req->timeout;
cmd->done = scsi_blk_pc_done;
} }
EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
static int scsi_prep_fn(struct request_queue *q, struct request *req) static int scsi_prep_fn(struct request_queue *q, struct request *req)
{ {
...@@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* happening now. * happening now.
*/ */
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
struct scsi_driver *drv;
int ret; int ret;
/* /*
...@@ -1371,16 +1370,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -1371,16 +1370,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
/* /*
* Initialize the actual SCSI command for this request. * Initialize the actual SCSI command for this request.
*/ */
if (req->rq_disk) { if (req->flags & REQ_BLOCK_PC) {
scsi_setup_blk_pc_cmnd(cmd);
} else if (req->rq_disk) {
struct scsi_driver *drv;
drv = *(struct scsi_driver **)req->rq_disk->private_data; drv = *(struct scsi_driver **)req->rq_disk->private_data;
if (unlikely(!drv->init_command(cmd))) { if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd); scsi_release_buffers(cmd);
scsi_put_command(cmd); scsi_put_command(cmd);
goto kill; goto kill;
} }
} else {
scsi_setup_blk_pc_cmnd(cmd);
cmd->done = scsi_generic_done;
} }
} }
......
...@@ -232,34 +232,12 @@ static void scsi_disk_put(struct scsi_disk *sdkp) ...@@ -232,34 +232,12 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
**/ **/
static int sd_init_command(struct scsi_cmnd * SCpnt) static int sd_init_command(struct scsi_cmnd * SCpnt)
{ {
unsigned int this_count, timeout;
struct gendisk *disk;
sector_t block;
struct scsi_device *sdp = SCpnt->device; struct scsi_device *sdp = SCpnt->device;
struct request *rq = SCpnt->request; struct request *rq = SCpnt->request;
struct gendisk *disk = rq->rq_disk;
timeout = sdp->timeout; sector_t block = rq->sector;
unsigned int this_count = SCpnt->request_bufflen >> 9;
/* unsigned int timeout = sdp->timeout;
* SG_IO from block layer already setup, just copy cdb basically
*/
if (blk_pc_request(rq)) {
scsi_setup_blk_pc_cmnd(SCpnt);
if (rq->timeout)
timeout = rq->timeout;
goto queue;
}
/*
* we only do REQ_CMD and REQ_BLOCK_PC
*/
if (!blk_fs_request(rq))
return 0;
disk = rq->rq_disk;
block = rq->sector;
this_count = SCpnt->request_bufflen >> 9;
SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
"count=%d\n", disk->disk_name, "count=%d\n", disk->disk_name,
...@@ -402,8 +380,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) ...@@ -402,8 +380,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt->transfersize = sdp->sector_size; SCpnt->transfersize = sdp->sector_size;
SCpnt->underflow = this_count << 9; SCpnt->underflow = this_count << 9;
SCpnt->allowed = SD_MAX_RETRIES; SCpnt->allowed = SD_MAX_RETRIES;
queue:
SCpnt->timeout_per_command = timeout; SCpnt->timeout_per_command = timeout;
/* /*
...@@ -837,15 +813,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) ...@@ -837,15 +813,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
relatively rare error condition, no care is taken to avoid relatively rare error condition, no care is taken to avoid
unnecessary additional work such as memcpy's that could be avoided. unnecessary additional work such as memcpy's that could be avoided.
*/ */
if (driver_byte(result) != 0 &&
/*
* If SG_IO from block layer then set good_bytes to stop retries;
* else if errors, check them, and if necessary prepare for
* (partial) retries.
*/
if (blk_pc_request(SCpnt->request))
good_bytes = this_count;
else if (driver_byte(result) != 0 &&
sense_valid && !sense_deferred) { sense_valid && !sense_deferred) {
switch (sshdr.sense_key) { switch (sshdr.sense_key) {
case MEDIUM_ERROR: case MEDIUM_ERROR:
......
...@@ -238,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt) ...@@ -238,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
case ILLEGAL_REQUEST: case ILLEGAL_REQUEST:
if (!(SCpnt->sense_buffer[0] & 0x90)) if (!(SCpnt->sense_buffer[0] & 0x90))
break; break;
if (!blk_fs_request(SCpnt->request))
break;
error_sector = (SCpnt->sense_buffer[3] << 24) | error_sector = (SCpnt->sense_buffer[3] << 24) |
(SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) | (SCpnt->sense_buffer[5] << 8) |
...@@ -317,23 +315,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) ...@@ -317,23 +315,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return 0; return 0;
} }
/*
* these are already setup, just copy cdb basically
*/
if (SCpnt->request->flags & REQ_BLOCK_PC) {
scsi_setup_blk_pc_cmnd(SCpnt);
if (SCpnt->timeout_per_command)
timeout = SCpnt->timeout_per_command;
goto queue;
}
if (!(SCpnt->request->flags & REQ_CMD)) {
blk_dump_rq_flags(SCpnt->request, "sr unsup command");
return 0;
}
/* /*
* we do lazy blocksize switching (when reading XA sectors, * we do lazy blocksize switching (when reading XA sectors,
* see CDROMREADMODE2 ioctl) * see CDROMREADMODE2 ioctl)
...@@ -422,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) ...@@ -422,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
*/ */
SCpnt->transfersize = cd->device->sector_size; SCpnt->transfersize = cd->device->sector_size;
SCpnt->underflow = this_count << 9; SCpnt->underflow = this_count << 9;
queue:
SCpnt->allowed = MAX_RETRIES; SCpnt->allowed = MAX_RETRIES;
SCpnt->timeout_per_command = timeout; SCpnt->timeout_per_command = timeout;
......
...@@ -194,7 +194,6 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); ...@@ -194,7 +194,6 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
static int st_probe(struct device *); static int st_probe(struct device *);
static int st_remove(struct device *); static int st_remove(struct device *);
static int st_init_command(struct scsi_cmnd *);
static void do_create_driverfs_files(void); static void do_create_driverfs_files(void);
static void do_remove_driverfs_files(void); static void do_remove_driverfs_files(void);
...@@ -207,7 +206,6 @@ static struct scsi_driver st_template = { ...@@ -207,7 +206,6 @@ static struct scsi_driver st_template = {
.probe = st_probe, .probe = st_probe,
.remove = st_remove, .remove = st_remove,
}, },
.init_command = st_init_command,
}; };
static int st_compression(struct scsi_tape *, int); static int st_compression(struct scsi_tape *, int);
...@@ -4181,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref) ...@@ -4181,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref)
return; return;
} }
static void st_intr(struct scsi_cmnd *SCpnt)
{
/*
* The caller should be checking the request's errors
* value.
*/
scsi_io_completion(SCpnt, SCpnt->bufflen, 0);
}
/*
* st_init_command: only called via the scsi_cmd_ioctl (block SG_IO)
* interface for REQ_BLOCK_PC commands.
*/
static int st_init_command(struct scsi_cmnd *SCpnt)
{
if (!(SCpnt->request->flags & REQ_BLOCK_PC))
return 0;
scsi_setup_blk_pc_cmnd(SCpnt);
SCpnt->done = st_intr;
return 1;
}
static int __init init_st(void) static int __init init_st(void)
{ {
validate_options(); validate_options();
......
...@@ -151,6 +151,5 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); ...@@ -151,6 +151,5 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
extern void scsi_put_command(struct scsi_cmnd *); extern void scsi_put_command(struct scsi_cmnd *);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd);
#endif /* _SCSI_SCSI_CMND_H */ #endif /* _SCSI_SCSI_CMND_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment