aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2007-08-04 11:06:25 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:49:30 -0400
commit7f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65 (patch)
treef2cceb87e2b6c9a66c66a8c8ceeb20bad09bb6fa /drivers/scsi/scsi_lib.c
parentd3849d512fb0ca1e369e3efcaec910a949f55f62 (diff)
[SCSI] move ULD attachment into the prep function
One of the intents of the block prep function was to allow ULDs to use it for preprocessing. The original SCSI model was to have a single prep function and add a pointer indirect filter to build the necessary commands. This patch reverses that, does away with the init_command field of the scsi_driver structure and makes ULDs attach directly to the prep function instead. The value is really that it allows us to begin to separate the ULDs from the SCSI mid layer (as long as they don't use any core functions---which is hard at the moment---a ULD doesn't even need SCSI to bind). Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 47d3cdd6ddf1..94d82cb96626 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1039,9 +1039,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
1039 printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, 1039 printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
1040 req->current_nr_sectors); 1040 req->current_nr_sectors);
1041 1041
1042 /* release the command and kill it */
1043 scsi_release_buffers(cmd);
1044 scsi_put_command(cmd);
1045 return BLKPREP_KILL; 1042 return BLKPREP_KILL;
1046} 1043}
1047 1044
@@ -1078,9 +1075,13 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
1078 scsi_io_completion(cmd, cmd->request_bufflen); 1075 scsi_io_completion(cmd, cmd->request_bufflen);
1079} 1076}
1080 1077
1081static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) 1078int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1082{ 1079{
1083 struct scsi_cmnd *cmd; 1080 struct scsi_cmnd *cmd;
1081 int ret = scsi_prep_state_check(sdev, req);
1082
1083 if (ret != BLKPREP_OK)
1084 return ret;
1084 1085
1085 cmd = scsi_get_cmd_from_req(sdev, req); 1086 cmd = scsi_get_cmd_from_req(sdev, req);
1086 if (unlikely(!cmd)) 1087 if (unlikely(!cmd))
@@ -1126,18 +1127,20 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1126 cmd->done = scsi_blk_pc_done; 1127 cmd->done = scsi_blk_pc_done;
1127 return BLKPREP_OK; 1128 return BLKPREP_OK;
1128} 1129}
1130EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
1129 1131
1130/* 1132/*
1131 * Setup a REQ_TYPE_FS command. These are simple read/write request 1133 * Setup a REQ_TYPE_FS command. These are simple read/write request
1132 * from filesystems that still need to be translated to SCSI CDBs from 1134 * from filesystems that still need to be translated to SCSI CDBs from
1133 * the ULD. 1135 * the ULD.
1134 */ 1136 */
1135static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) 1137int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
1136{ 1138{
1137 struct scsi_cmnd *cmd; 1139 struct scsi_cmnd *cmd;
1138 struct scsi_driver *drv; 1140 int ret = scsi_prep_state_check(sdev, req);
1139 int ret;
1140 1141
1142 if (ret != BLKPREP_OK)
1143 return ret;
1141 /* 1144 /*
1142 * Filesystem requests must transfer data. 1145 * Filesystem requests must transfer data.
1143 */ 1146 */
@@ -1147,26 +1150,12 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
1147 if (unlikely(!cmd)) 1150 if (unlikely(!cmd))
1148 return BLKPREP_DEFER; 1151 return BLKPREP_DEFER;
1149 1152
1150 ret = scsi_init_io(cmd); 1153 return scsi_init_io(cmd);
1151 if (unlikely(ret))
1152 return ret;
1153
1154 /*
1155 * Initialize the actual SCSI command for this request.
1156 */
1157 drv = *(struct scsi_driver **)req->rq_disk->private_data;
1158 if (unlikely(!drv->init_command(cmd))) {
1159 scsi_release_buffers(cmd);
1160 scsi_put_command(cmd);
1161 return BLKPREP_KILL;
1162 }
1163
1164 return BLKPREP_OK;
1165} 1154}
1155EXPORT_SYMBOL(scsi_setup_fs_cmnd);
1166 1156
1167static int scsi_prep_fn(struct request_queue *q, struct request *req) 1157int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
1168{ 1158{
1169 struct scsi_device *sdev = q->queuedata;
1170 int ret = BLKPREP_OK; 1159 int ret = BLKPREP_OK;
1171 1160
1172 /* 1161 /*
@@ -1212,35 +1201,25 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
1212 ret = BLKPREP_KILL; 1201 ret = BLKPREP_KILL;
1213 break; 1202 break;
1214 } 1203 }
1215
1216 if (ret != BLKPREP_OK)
1217 goto out;
1218 } 1204 }
1205 return ret;
1206}
1207EXPORT_SYMBOL(scsi_prep_state_check);
1219 1208
1220 switch (req->cmd_type) { 1209int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
1221 case REQ_TYPE_BLOCK_PC: 1210{
1222 ret = scsi_setup_blk_pc_cmnd(sdev, req); 1211 struct scsi_device *sdev = q->queuedata;
1223 break;
1224 case REQ_TYPE_FS:
1225 ret = scsi_setup_fs_cmnd(sdev, req);
1226 break;
1227 default:
1228 /*
1229 * All other command types are not supported.
1230 *
1231 * Note that these days the SCSI subsystem does not use
1232 * REQ_TYPE_SPECIAL requests anymore. These are only used
1233 * (directly or via blk_insert_request) by non-SCSI drivers.
1234 */
1235 blk_dump_rq_flags(req, "SCSI bad req");
1236 ret = BLKPREP_KILL;
1237 break;
1238 }
1239 1212
1240 out:
1241 switch (ret) { 1213 switch (ret) {
1242 case BLKPREP_KILL: 1214 case BLKPREP_KILL:
1243 req->errors = DID_NO_CONNECT << 16; 1215 req->errors = DID_NO_CONNECT << 16;
1216 /* release the command and kill it */
1217 if (req->special) {
1218 struct scsi_cmnd *cmd = req->special;
1219 scsi_release_buffers(cmd);
1220 scsi_put_command(cmd);
1221 req->special = NULL;
1222 }
1244 break; 1223 break;
1245 case BLKPREP_DEFER: 1224 case BLKPREP_DEFER:
1246 /* 1225 /*
@@ -1257,6 +1236,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
1257 1236
1258 return ret; 1237 return ret;
1259} 1238}
1239EXPORT_SYMBOL(scsi_prep_return);
1240
1241static int scsi_prep_fn(struct request_queue *q, struct request *req)
1242{
1243 struct scsi_device *sdev = q->queuedata;
1244 int ret = BLKPREP_KILL;
1245
1246 if (req->cmd_type == REQ_TYPE_BLOCK_PC)
1247 ret = scsi_setup_blk_pc_cmnd(sdev, req);
1248 return scsi_prep_return(q, req, ret);
1249}
1260 1250
1261/* 1251/*
1262 * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else 1252 * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else