* [PATCH] fix all REQ_BLOCK_PC retries and requeues (take2)
@ 2005-09-18 21:04 Mike Christie
2005-09-18 23:14 ` Mike Christie
0 siblings, 1 reply; 2+ messages in thread
From: Mike Christie @ 2005-09-18 21:04 UTC (permalink / raw)
To: linux-scsi, axboe
sd and st handle REQ_BLOCK_PC command setup the same, and
except for a bug in st_intr they would handle completion
exactly the same. And it seems we want scsi_execute*
to handle setup and completion in the same way as
the ULDs so the patch below moves everyone to use
scsi_generic_done for REQ_BLOCK_PC commands.
This patch also adds a reties count onto the request
so that we handle command retries like we used to.
This patch was made against scsi-rc-fixes.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c
+++ b/drivers/block/scsi_ioctl.c
@@ -302,6 +302,7 @@ static int sg_io(struct file *file, requ
rq->timeout = q->sg_timeout;
if (!rq->timeout)
rq->timeout = BLK_DEFAULT_TIMEOUT;
+ rq->retries = 1;
start_time = jiffies;
@@ -412,6 +413,7 @@ static int sg_scsi_ioctl(struct file *fi
rq->timeout = BLK_DEFAULT_TIMEOUT;
break;
}
+ rq->retries = 1;
memset(sense, 0, sizeof(sense));
rq->sense = sense;
@@ -570,6 +572,7 @@ int scsi_cmd_ioctl(struct file *file, st
rq->data = NULL;
rq->data_len = 0;
rq->timeout = BLK_DEFAULT_TIMEOUT;
+ rq->retries = 1;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd[0] = GPCMD_START_STOP_UNIT;
rq->cmd[4] = 0x02 + (close != 0);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -337,6 +337,7 @@ int scsi_execute(struct scsi_device *sde
memcpy(req->cmd, cmd, req->cmd_len);
req->sense = sense;
req->sense_len = 0;
+ req->retries = retries;
req->timeout = timeout;
req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
@@ -1125,7 +1126,13 @@ static int scsi_issue_flush_fn(request_q
static void scsi_generic_done(struct scsi_cmnd *cmd)
{
BUG_ON(!blk_pc_request(cmd->request));
- scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
+ /*
+ * This will complete the whole command with uptodate=1 so
+ * as far as the block layer is concerned the command completed
+ * successfully. Since this is REQ_BLOCK_PC command though the
+ * caller should check the errors value to check for errors
+ */
+ scsi_io_completion(cmd, cmd->bufflen, 0);
}
static int scsi_prep_fn(struct request_queue *q, struct request *req)
@@ -1255,7 +1262,7 @@ static int scsi_prep_fn(struct request_q
/*
* Initialize the actual SCSI command for this request.
*/
- if (req->rq_disk) {
+ if (!blk_pc_request(req)) {
drv = *(struct scsi_driver **)req->rq_disk->private_data;
if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd);
@@ -1273,7 +1280,7 @@ static int scsi_prep_fn(struct request_q
cmd->sc_data_direction = DMA_NONE;
cmd->transfersize = req->data_len;
- cmd->allowed = 3;
+ cmd->allowed = req->retries;
cmd->timeout_per_command = req->timeout;
cmd->done = scsi_generic_done;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -86,7 +86,6 @@
* Number of allowed retries
*/
#define SD_MAX_RETRIES 5
-#define SD_PASSTHROUGH_RETRIES 1
static void scsi_disk_release(struct kref *kref);
@@ -219,41 +218,14 @@ static void scsi_disk_put(struct scsi_di
**/
static int sd_init_command(struct scsi_cmnd * SCpnt)
{
- unsigned int this_count, timeout;
+ unsigned int this_count;
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)) {
- if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
- return 0;
-
- memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
- if (rq_data_dir(rq) == WRITE)
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- else if (rq->data_len)
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
- else
- SCpnt->sc_data_direction = DMA_NONE;
-
- this_count = rq->data_len;
- if (rq->timeout)
- timeout = rq->timeout;
-
- SCpnt->transfersize = rq->data_len;
- SCpnt->allowed = SD_PASSTHROUGH_RETRIES;
- goto queue;
- }
-
- /*
- * we only do REQ_CMD and REQ_BLOCK_PC
+ * we only do REQ_CMD
*/
if (!blk_fs_request(rq))
return 0;
@@ -390,10 +362,7 @@ static int sd_init_command(struct scsi_c
SCpnt->transfersize = sdp->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = SD_MAX_RETRIES;
-
-queue:
- SCpnt->timeout_per_command = timeout;
-
+ SCpnt->timeout_per_command = sdp->timeout;
/*
* This is the completion routine we use. This is matched in terms
* of capability to this function.
@@ -862,15 +831,7 @@ static void sd_rw_intr(struct scsi_cmnd
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 &&
- sense_valid && !sense_deferred) {
+ if (driver_byte(result) != 0 && sense_valid && !sense_deferred) {
switch (sshdr.sense_key) {
case MEDIUM_ERROR:
if (!blk_fs_request(SCpnt->request))
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -196,7 +196,6 @@ static int sgl_unmap_user_pages(struct s
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);
@@ -209,7 +208,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);
@@ -4185,42 +4183,6 @@ static void scsi_tape_release(struct kre
return;
}
-static void st_intr(struct scsi_cmnd *SCpnt)
-{
- scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen), 1);
-}
-
-/*
- * 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)
-{
- struct request *rq;
-
- if (!(SCpnt->request->flags & REQ_BLOCK_PC))
- return 0;
-
- rq = SCpnt->request;
- if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
- return 0;
-
- memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
-
- if (rq_data_dir(rq) == WRITE)
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- else if (rq->data_len)
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
- else
- SCpnt->sc_data_direction = DMA_NONE;
-
- SCpnt->timeout_per_command = rq->timeout;
- SCpnt->transfersize = rq->data_len;
- SCpnt->done = st_intr;
- return 1;
-}
-
static int __init init_st(void)
{
validate_options();
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -184,6 +184,7 @@ struct request {
void *sense;
unsigned int timeout;
+ int retries;
/*
* For Power Management requests
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] fix all REQ_BLOCK_PC retries and requeues (take2)
2005-09-18 21:04 [PATCH] fix all REQ_BLOCK_PC retries and requeues (take2) Mike Christie
@ 2005-09-18 23:14 ` Mike Christie
0 siblings, 0 replies; 2+ messages in thread
From: Mike Christie @ 2005-09-18 23:14 UTC (permalink / raw)
To: linux-scsi; +Cc: axboe
On Sun, 2005-09-18 at 16:04 -0500, Mike Christie wrote:
> sd and st handle REQ_BLOCK_PC command setup the same, and
crap, I need to go to sleep. I guess those other patches here
http://marc.theaimsgroup.com/?l=linux-scsi&m=112708362822874&w=2
http://marc.theaimsgroup.com/?l=linux-scsi&m=112708367105404&w=2
were right because sr wants is special.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2005-09-18 23:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-18 21:04 [PATCH] fix all REQ_BLOCK_PC retries and requeues (take2) Mike Christie
2005-09-18 23:14 ` Mike Christie
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).