diff options
author | Christoph Hellwig <hch@lst.de> | 2006-01-06 18:34:07 +0100 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2006-01-14 17:54:45 +0100 |
commit | 776b23a0363d99ca402edc1aba1db8099b747b33 (patch) | |
tree | 20cab193388facc2506e3de2a3d931ab22d81ae4 /drivers/scsi | |
parent | [SCSI] sas: fix removal of devices behind expanders (diff) | |
download | linux-776b23a0363d99ca402edc1aba1db8099b747b33.tar.xz linux-776b23a0363d99ca402edc1aba1db8099b747b33.zip |
[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: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 16 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 42 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 21 | ||||
-rw-r--r-- | drivers/scsi/st.c | 25 |
4 files changed, 13 insertions, 91 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 00c9bf383e23..3574ba935af8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, 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)); /* @@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) 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; @@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) cmd->transfersize = req->data_len; cmd->allowed = req->retries; 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) { @@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) * happening now. */ if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { - struct scsi_driver *drv; int ret; /* @@ -1371,16 +1370,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) /* * 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; if (unlikely(!drv->init_command(cmd))) { scsi_release_buffers(cmd); scsi_put_command(cmd); goto kill; } - } else { - scsi_setup_blk_pc_cmnd(cmd); - cmd->done = scsi_generic_done; } } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fbd8e1bbad38..930db398d107 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -232,34 +232,12 @@ static void scsi_disk_put(struct scsi_disk *sdkp) **/ 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 request *rq = SCpnt->request; - - 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; + struct gendisk *disk = rq->rq_disk; + sector_t block = rq->sector; + unsigned int this_count = SCpnt->request_bufflen >> 9; + unsigned int timeout = sdp->timeout; SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " "count=%d\n", disk->disk_name, @@ -402,8 +380,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->transfersize = sdp->sector_size; SCpnt->underflow = this_count << 9; SCpnt->allowed = SD_MAX_RETRIES; - -queue: SCpnt->timeout_per_command = timeout; /* @@ -837,15 +813,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) relatively rare error condition, no care is taken to avoid unnecessary additional work such as memcpy's that could be avoided. */ - - /* - * 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 && + if (driver_byte(result) != 0 && sense_valid && !sense_deferred) { switch (sshdr.sense_key) { case MEDIUM_ERROR: diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 18a3b756c63c..dd8050392d01 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -238,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt) case ILLEGAL_REQUEST: if (!(SCpnt->sense_buffer[0] & 0x90)) break; - if (!blk_fs_request(SCpnt->request)) - break; error_sector = (SCpnt->sense_buffer[3] << 24) | (SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[5] << 8) | @@ -318,23 +316,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) } /* - * 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, * see CDROMREADMODE2 ioctl) */ @@ -422,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) */ SCpnt->transfersize = cd->device->sector_size; SCpnt->underflow = this_count << 9; - -queue: SCpnt->allowed = MAX_RETRIES; SCpnt->timeout_per_command = timeout; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 6e4a36af58c3..13b1d3aac265 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -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_remove(struct device *); -static int st_init_command(struct scsi_cmnd *); static void do_create_driverfs_files(void); static void do_remove_driverfs_files(void); @@ -207,7 +206,6 @@ static struct scsi_driver st_template = { .probe = st_probe, .remove = st_remove, }, - .init_command = st_init_command, }; static int st_compression(struct scsi_tape *, int); @@ -4181,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref) 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) { validate_options(); |