aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2005-09-10 17:45:35 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-10 22:02:25 -0400
commit6f16b5359ceb96780eac4178393b0e8a3c8aa1ea (patch)
treec45e9bf0b69fb94317b572c8b3042417d6046e4f /drivers/scsi/scsi_lib.c
parent146f7262ee0ec7fc6882f06e5fcb13883308073c (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>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c24
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/*