diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2005-09-10 16:45:35 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-10 21:02:25 -0500 |
commit | 6f16b5359ceb96780eac4178393b0e8a3c8aa1ea (patch) | |
tree | c45e9bf0b69fb94317b572c8b3042417d6046e4f | |
parent | 146f7262ee0ec7fc6882f06e5fcb13883308073c (diff) | |
download | op-kernel-dev-6f16b5359ceb96780eac4178393b0e8a3c8aa1ea.zip op-kernel-dev-6f16b5359ceb96780eac4178393b0e8a3c8aa1ea.tar.gz |
[SCSI] set error value when failing commands in prep_fn
set DID_NO_CONNECT for the BLKPREP_KILL case and correct a few
BLKPREP_DEFER cases that weren't checking for the need to plug the
queue.
Signed-Off-By: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d8d9848..863bb64 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1146,7 +1146,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) if (unlikely(!scsi_device_online(sdev))) { printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n", sdev->host->host_no, sdev->id, sdev->lun); - return BLKPREP_KILL; + goto kill; } if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { /* OK, we're not in a running state don't prep @@ -1156,7 +1156,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) * at all allowed down */ printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n", sdev->host->host_no, sdev->id, sdev->lun); - return BLKPREP_KILL; + goto kill; } /* OK, we only allow special commands (i.e. not * user initiated ones */ @@ -1188,11 +1188,11 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) { if(specials_only == SDEV_QUIESCE || specials_only == SDEV_BLOCK) - return BLKPREP_DEFER; + goto defer; printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n", sdev->host->host_no, sdev->id, sdev->lun); - return BLKPREP_KILL; + goto kill; } @@ -1210,7 +1210,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) cmd->tag = req->tag; } else { blk_dump_rq_flags(req, "SCSI bad req"); - return BLKPREP_KILL; + goto kill; } /* note the overloading of req->special. When the tag @@ -1248,8 +1248,13 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) * required). */ ret = scsi_init_io(cmd); - if (ret) /* BLKPREP_KILL return also releases the command */ - return ret; + switch(ret) { + case BLKPREP_KILL: + /* BLKPREP_KILL return also releases the command */ + goto kill; + case BLKPREP_DEFER: + goto defer; + } /* * Initialize the actual SCSI command for this request. @@ -1259,7 +1264,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) if (unlikely(!drv->init_command(cmd))) { scsi_release_buffers(cmd); scsi_put_command(cmd); - return BLKPREP_KILL; + goto kill; } } else { memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); @@ -1290,6 +1295,9 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) if (sdev->device_busy == 0) blk_plug_device(q); return BLKPREP_DEFER; + kill: + req->errors = DID_NO_CONNECT << 16; + return BLKPREP_KILL; } /* |