diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 84 |
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 | ||
1081 | static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | 1078 | int 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 | } |
1130 | EXPORT_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 | */ |
1135 | static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | 1137 | int 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 | } |
1155 | EXPORT_SYMBOL(scsi_setup_fs_cmnd); | ||
1166 | 1156 | ||
1167 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1157 | int 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 | } | ||
1207 | EXPORT_SYMBOL(scsi_prep_state_check); | ||
1219 | 1208 | ||
1220 | switch (req->cmd_type) { | 1209 | int 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 | } |
1239 | EXPORT_SYMBOL(scsi_prep_return); | ||
1240 | |||
1241 | static 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 |