diff options
author | Christoph Hellwig <hch@lst.de> | 2006-01-06 12:34:07 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2006-01-14 11:54:45 -0500 |
commit | 776b23a0363d99ca402edc1aba1db8099b747b33 (patch) | |
tree | 20cab193388facc2506e3de2a3d931ab22d81ae4 | |
parent | d4054239929479907f20b9d68c905589125ad343 (diff) |
[SCSI] always handle REQ_BLOCK_PC requests in common code
LLDDs should never see REQ_BLOCK_PC requests, we can handle them just
fine in the core code. There is a small behaviour change in that some
check in sr's rw_intr are bypassed, but I consider the old behaviour
a bug.
Mike found this cleanup opportunity and provdided early patches, so all
the credit goes to him, even if I redid the patches from scratch beause
that was easier than forward-porting the old patches.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 16 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 42 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 21 | ||||
-rw-r--r-- | drivers/scsi/st.c | 25 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 1 |
5 files changed, 13 insertions, 92 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 00c9bf383e23..3574ba935af8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | |||
1212 | return -EOPNOTSUPP; | 1212 | return -EOPNOTSUPP; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static void scsi_generic_done(struct scsi_cmnd *cmd) | 1215 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) |
1216 | { | 1216 | { |
1217 | BUG_ON(!blk_pc_request(cmd->request)); | 1217 | BUG_ON(!blk_pc_request(cmd->request)); |
1218 | /* | 1218 | /* |
@@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) | |||
1224 | scsi_io_completion(cmd, cmd->bufflen, 0); | 1224 | scsi_io_completion(cmd, cmd->bufflen, 0); |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1227 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
1228 | { | 1228 | { |
1229 | struct request *req = cmd->request; | 1229 | struct request *req = cmd->request; |
1230 | 1230 | ||
@@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | |||
1241 | cmd->transfersize = req->data_len; | 1241 | cmd->transfersize = req->data_len; |
1242 | cmd->allowed = req->retries; | 1242 | cmd->allowed = req->retries; |
1243 | cmd->timeout_per_command = req->timeout; | 1243 | cmd->timeout_per_command = req->timeout; |
1244 | cmd->done = scsi_blk_pc_done; | ||
1244 | } | 1245 | } |
1245 | EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd); | ||
1246 | 1246 | ||
1247 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1247 | static int scsi_prep_fn(struct request_queue *q, struct request *req) |
1248 | { | 1248 | { |
@@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1339 | * happening now. | 1339 | * happening now. |
1340 | */ | 1340 | */ |
1341 | if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { | 1341 | if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { |
1342 | struct scsi_driver *drv; | ||
1343 | int ret; | 1342 | int ret; |
1344 | 1343 | ||
1345 | /* | 1344 | /* |
@@ -1371,16 +1370,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1371 | /* | 1370 | /* |
1372 | * Initialize the actual SCSI command for this request. | 1371 | * Initialize the actual SCSI command for this request. |
1373 | */ | 1372 | */ |
1374 | if (req->rq_disk) { | 1373 | if (req->flags & REQ_BLOCK_PC) { |
1374 | scsi_setup_blk_pc_cmnd(cmd); | ||
1375 | } else if (req->rq_disk) { | ||
1376 | struct scsi_driver *drv; | ||
1377 | |||
1375 | drv = *(struct scsi_driver **)req->rq_disk->private_data; | 1378 | drv = *(struct scsi_driver **)req->rq_disk->private_data; |
1376 | if (unlikely(!drv->init_command(cmd))) { | 1379 | if (unlikely(!drv->init_command(cmd))) { |
1377 | scsi_release_buffers(cmd); | 1380 | scsi_release_buffers(cmd); |
1378 | scsi_put_command(cmd); | 1381 | scsi_put_command(cmd); |
1379 | goto kill; | 1382 | goto kill; |
1380 | } | 1383 | } |
1381 | } else { | ||
1382 | scsi_setup_blk_pc_cmnd(cmd); | ||
1383 | cmd->done = scsi_generic_done; | ||
1384 | } | 1384 | } |
1385 | } | 1385 | } |
1386 | 1386 | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fbd8e1bbad38..930db398d107 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -232,34 +232,12 @@ static void scsi_disk_put(struct scsi_disk *sdkp) | |||
232 | **/ | 232 | **/ |
233 | static int sd_init_command(struct scsi_cmnd * SCpnt) | 233 | static int sd_init_command(struct scsi_cmnd * SCpnt) |
234 | { | 234 | { |
235 | unsigned int this_count, timeout; | ||
236 | struct gendisk *disk; | ||
237 | sector_t block; | ||
238 | struct scsi_device *sdp = SCpnt->device; | 235 | struct scsi_device *sdp = SCpnt->device; |
239 | struct request *rq = SCpnt->request; | 236 | struct request *rq = SCpnt->request; |
240 | 237 | struct gendisk *disk = rq->rq_disk; | |
241 | timeout = sdp->timeout; | 238 | sector_t block = rq->sector; |
242 | 239 | unsigned int this_count = SCpnt->request_bufflen >> 9; | |
243 | /* | 240 | unsigned int timeout = sdp->timeout; |
244 | * SG_IO from block layer already setup, just copy cdb basically | ||
245 | */ | ||
246 | if (blk_pc_request(rq)) { | ||
247 | scsi_setup_blk_pc_cmnd(SCpnt); | ||
248 | if (rq->timeout) | ||
249 | timeout = rq->timeout; | ||
250 | |||
251 | goto queue; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * we only do REQ_CMD and REQ_BLOCK_PC | ||
256 | */ | ||
257 | if (!blk_fs_request(rq)) | ||
258 | return 0; | ||
259 | |||
260 | disk = rq->rq_disk; | ||
261 | block = rq->sector; | ||
262 | this_count = SCpnt->request_bufflen >> 9; | ||
263 | 241 | ||
264 | SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " | 242 | SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " |
265 | "count=%d\n", disk->disk_name, | 243 | "count=%d\n", disk->disk_name, |
@@ -402,8 +380,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
402 | SCpnt->transfersize = sdp->sector_size; | 380 | SCpnt->transfersize = sdp->sector_size; |
403 | SCpnt->underflow = this_count << 9; | 381 | SCpnt->underflow = this_count << 9; |
404 | SCpnt->allowed = SD_MAX_RETRIES; | 382 | SCpnt->allowed = SD_MAX_RETRIES; |
405 | |||
406 | queue: | ||
407 | SCpnt->timeout_per_command = timeout; | 383 | SCpnt->timeout_per_command = timeout; |
408 | 384 | ||
409 | /* | 385 | /* |
@@ -837,15 +813,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
837 | relatively rare error condition, no care is taken to avoid | 813 | relatively rare error condition, no care is taken to avoid |
838 | unnecessary additional work such as memcpy's that could be avoided. | 814 | unnecessary additional work such as memcpy's that could be avoided. |
839 | */ | 815 | */ |
840 | 816 | if (driver_byte(result) != 0 && | |
841 | /* | ||
842 | * If SG_IO from block layer then set good_bytes to stop retries; | ||
843 | * else if errors, check them, and if necessary prepare for | ||
844 | * (partial) retries. | ||
845 | */ | ||
846 | if (blk_pc_request(SCpnt->request)) | ||
847 | good_bytes = this_count; | ||
848 | else if (driver_byte(result) != 0 && | ||
849 | sense_valid && !sense_deferred) { | 817 | sense_valid && !sense_deferred) { |
850 | switch (sshdr.sense_key) { | 818 | switch (sshdr.sense_key) { |
851 | case MEDIUM_ERROR: | 819 | case MEDIUM_ERROR: |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 18a3b756c63c..dd8050392d01 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -238,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
238 | case ILLEGAL_REQUEST: | 238 | case ILLEGAL_REQUEST: |
239 | if (!(SCpnt->sense_buffer[0] & 0x90)) | 239 | if (!(SCpnt->sense_buffer[0] & 0x90)) |
240 | break; | 240 | break; |
241 | if (!blk_fs_request(SCpnt->request)) | ||
242 | break; | ||
243 | error_sector = (SCpnt->sense_buffer[3] << 24) | | 241 | error_sector = (SCpnt->sense_buffer[3] << 24) | |
244 | (SCpnt->sense_buffer[4] << 16) | | 242 | (SCpnt->sense_buffer[4] << 16) | |
245 | (SCpnt->sense_buffer[5] << 8) | | 243 | (SCpnt->sense_buffer[5] << 8) | |
@@ -318,23 +316,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
318 | } | 316 | } |
319 | 317 | ||
320 | /* | 318 | /* |
321 | * these are already setup, just copy cdb basically | ||
322 | */ | ||
323 | if (SCpnt->request->flags & REQ_BLOCK_PC) { | ||
324 | scsi_setup_blk_pc_cmnd(SCpnt); | ||
325 | |||
326 | if (SCpnt->timeout_per_command) | ||
327 | timeout = SCpnt->timeout_per_command; | ||
328 | |||
329 | goto queue; | ||
330 | } | ||
331 | |||
332 | if (!(SCpnt->request->flags & REQ_CMD)) { | ||
333 | blk_dump_rq_flags(SCpnt->request, "sr unsup command"); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * we do lazy blocksize switching (when reading XA sectors, | 319 | * we do lazy blocksize switching (when reading XA sectors, |
339 | * see CDROMREADMODE2 ioctl) | 320 | * see CDROMREADMODE2 ioctl) |
340 | */ | 321 | */ |
@@ -422,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
422 | */ | 403 | */ |
423 | SCpnt->transfersize = cd->device->sector_size; | 404 | SCpnt->transfersize = cd->device->sector_size; |
424 | SCpnt->underflow = this_count << 9; | 405 | SCpnt->underflow = this_count << 9; |
425 | |||
426 | queue: | ||
427 | SCpnt->allowed = MAX_RETRIES; | 406 | SCpnt->allowed = MAX_RETRIES; |
428 | SCpnt->timeout_per_command = timeout; | 407 | SCpnt->timeout_per_command = timeout; |
429 | 408 | ||
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 6e4a36af58c3..13b1d3aac265 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -194,7 +194,6 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); | |||
194 | 194 | ||
195 | static int st_probe(struct device *); | 195 | static int st_probe(struct device *); |
196 | static int st_remove(struct device *); | 196 | static int st_remove(struct device *); |
197 | static int st_init_command(struct scsi_cmnd *); | ||
198 | 197 | ||
199 | static void do_create_driverfs_files(void); | 198 | static void do_create_driverfs_files(void); |
200 | static void do_remove_driverfs_files(void); | 199 | static void do_remove_driverfs_files(void); |
@@ -207,7 +206,6 @@ static struct scsi_driver st_template = { | |||
207 | .probe = st_probe, | 206 | .probe = st_probe, |
208 | .remove = st_remove, | 207 | .remove = st_remove, |
209 | }, | 208 | }, |
210 | .init_command = st_init_command, | ||
211 | }; | 209 | }; |
212 | 210 | ||
213 | static int st_compression(struct scsi_tape *, int); | 211 | static int st_compression(struct scsi_tape *, int); |
@@ -4181,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref) | |||
4181 | return; | 4179 | return; |
4182 | } | 4180 | } |
4183 | 4181 | ||
4184 | static void st_intr(struct scsi_cmnd *SCpnt) | ||
4185 | { | ||
4186 | /* | ||
4187 | * The caller should be checking the request's errors | ||
4188 | * value. | ||
4189 | */ | ||
4190 | scsi_io_completion(SCpnt, SCpnt->bufflen, 0); | ||
4191 | } | ||
4192 | |||
4193 | /* | ||
4194 | * st_init_command: only called via the scsi_cmd_ioctl (block SG_IO) | ||
4195 | * interface for REQ_BLOCK_PC commands. | ||
4196 | */ | ||
4197 | static int st_init_command(struct scsi_cmnd *SCpnt) | ||
4198 | { | ||
4199 | if (!(SCpnt->request->flags & REQ_BLOCK_PC)) | ||
4200 | return 0; | ||
4201 | |||
4202 | scsi_setup_blk_pc_cmnd(SCpnt); | ||
4203 | SCpnt->done = st_intr; | ||
4204 | return 1; | ||
4205 | } | ||
4206 | |||
4207 | static int __init init_st(void) | 4182 | static int __init init_st(void) |
4208 | { | 4183 | { |
4209 | validate_options(); | 4184 | validate_options(); |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 41cfc29be899..7529f4388bb4 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -151,6 +151,5 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); | |||
151 | extern void scsi_put_command(struct scsi_cmnd *); | 151 | extern void scsi_put_command(struct scsi_cmnd *); |
152 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); | 152 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); |
153 | extern void scsi_finish_command(struct scsi_cmnd *cmd); | 153 | extern void scsi_finish_command(struct scsi_cmnd *cmd); |
154 | extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd); | ||
155 | 154 | ||
156 | #endif /* _SCSI_SCSI_CMND_H */ | 155 | #endif /* _SCSI_SCSI_CMND_H */ |