[SCSI] always handle REQ_BLOCK_PC requests in common code
Christoph Hellwig [Fri, 6 Jan 2006 17:34:07 +0000 (18:34 +0100)]
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>

drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/scsi/st.c
include/scsi/scsi_cmnd.h

index 00c9bf3..3574ba9 100644 (file)
@@ -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;
                }
        }
 
index fbd8e1b..930db39 100644 (file)
@@ -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:
index 18a3b75..dd80503 100644 (file)
@@ -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;
 
index 6e4a36a..13b1d3a 100644 (file)
@@ -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();
index 41cfc29..7529f43 100644 (file)
@@ -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_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
 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 */