diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2005-09-10 17:45:35 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-10 22:02:25 -0400 |
commit | 6f16b5359ceb96780eac4178393b0e8a3c8aa1ea (patch) | |
tree | c45e9bf0b69fb94317b572c8b3042417d6046e4f | |
parent | 146f7262ee0ec7fc6882f06e5fcb13883308073c (diff) |
[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 d8d984841534..863bb6495daa 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) | |||
1146 | if (unlikely(!scsi_device_online(sdev))) { | 1146 | if (unlikely(!scsi_device_online(sdev))) { |
1147 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n", | 1147 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n", |
1148 | sdev->host->host_no, sdev->id, sdev->lun); | 1148 | sdev->host->host_no, sdev->id, sdev->lun); |
1149 | return BLKPREP_KILL; | 1149 | goto kill; |
1150 | } | 1150 | } |
1151 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { | 1151 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { |
1152 | /* OK, we're not in a running state don't prep | 1152 | /* 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) | |||
1156 | * at all allowed down */ | 1156 | * at all allowed down */ |
1157 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n", | 1157 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n", |
1158 | sdev->host->host_no, sdev->id, sdev->lun); | 1158 | sdev->host->host_no, sdev->id, sdev->lun); |
1159 | return BLKPREP_KILL; | 1159 | goto kill; |
1160 | } | 1160 | } |
1161 | /* OK, we only allow special commands (i.e. not | 1161 | /* OK, we only allow special commands (i.e. not |
1162 | * user initiated ones */ | 1162 | * user initiated ones */ |
@@ -1188,11 +1188,11 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1188 | if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) { | 1188 | if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) { |
1189 | if(specials_only == SDEV_QUIESCE || | 1189 | if(specials_only == SDEV_QUIESCE || |
1190 | specials_only == SDEV_BLOCK) | 1190 | specials_only == SDEV_BLOCK) |
1191 | return BLKPREP_DEFER; | 1191 | goto defer; |
1192 | 1192 | ||
1193 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n", | 1193 | printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n", |
1194 | sdev->host->host_no, sdev->id, sdev->lun); | 1194 | sdev->host->host_no, sdev->id, sdev->lun); |
1195 | return BLKPREP_KILL; | 1195 | goto kill; |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | 1198 | ||
@@ -1210,7 +1210,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1210 | cmd->tag = req->tag; | 1210 | cmd->tag = req->tag; |
1211 | } else { | 1211 | } else { |
1212 | blk_dump_rq_flags(req, "SCSI bad req"); | 1212 | blk_dump_rq_flags(req, "SCSI bad req"); |
1213 | return BLKPREP_KILL; | 1213 | goto kill; |
1214 | } | 1214 | } |
1215 | 1215 | ||
1216 | /* note the overloading of req->special. When the tag | 1216 | /* 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) | |||
1248 | * required). | 1248 | * required). |
1249 | */ | 1249 | */ |
1250 | ret = scsi_init_io(cmd); | 1250 | ret = scsi_init_io(cmd); |
1251 | if (ret) /* BLKPREP_KILL return also releases the command */ | 1251 | switch(ret) { |
1252 | return ret; | 1252 | case BLKPREP_KILL: |
1253 | /* BLKPREP_KILL return also releases the command */ | ||
1254 | goto kill; | ||
1255 | case BLKPREP_DEFER: | ||
1256 | goto defer; | ||
1257 | } | ||
1253 | 1258 | ||
1254 | /* | 1259 | /* |
1255 | * Initialize the actual SCSI command for this request. | 1260 | * Initialize the actual SCSI command for this request. |
@@ -1259,7 +1264,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1259 | if (unlikely(!drv->init_command(cmd))) { | 1264 | if (unlikely(!drv->init_command(cmd))) { |
1260 | scsi_release_buffers(cmd); | 1265 | scsi_release_buffers(cmd); |
1261 | scsi_put_command(cmd); | 1266 | scsi_put_command(cmd); |
1262 | return BLKPREP_KILL; | 1267 | goto kill; |
1263 | } | 1268 | } |
1264 | } else { | 1269 | } else { |
1265 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1270 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); |
@@ -1290,6 +1295,9 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1290 | if (sdev->device_busy == 0) | 1295 | if (sdev->device_busy == 0) |
1291 | blk_plug_device(q); | 1296 | blk_plug_device(q); |
1292 | return BLKPREP_DEFER; | 1297 | return BLKPREP_DEFER; |
1298 | kill: | ||
1299 | req->errors = DID_NO_CONNECT << 16; | ||
1300 | return BLKPREP_KILL; | ||
1293 | } | 1301 | } |
1294 | 1302 | ||
1295 | /* | 1303 | /* |