diff options
-rw-r--r-- | drivers/scsi/scsi_lib.c | 84 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 48 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 59 | ||||
-rw-r--r-- | include/scsi/scsi_driver.h | 9 | ||||
-rw-r--r-- | include/scsi/sd.h | 1 |
5 files changed, 119 insertions, 82 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 |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2c6116fd4578..38a41415004b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -240,7 +240,6 @@ static struct scsi_driver sd_template = { | |||
240 | .shutdown = sd_shutdown, | 240 | .shutdown = sd_shutdown, |
241 | }, | 241 | }, |
242 | .rescan = sd_rescan, | 242 | .rescan = sd_rescan, |
243 | .init_command = sd_init_command, | ||
244 | }; | 243 | }; |
245 | 244 | ||
246 | /* | 245 | /* |
@@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) | |||
331 | * | 330 | * |
332 | * Returns 1 if successful and 0 if error (or cannot be done now). | 331 | * Returns 1 if successful and 0 if error (or cannot be done now). |
333 | **/ | 332 | **/ |
334 | static int sd_init_command(struct scsi_cmnd * SCpnt) | 333 | static int sd_prep_fn(struct request_queue *q, struct request *rq) |
335 | { | 334 | { |
336 | struct scsi_device *sdp = SCpnt->device; | 335 | struct scsi_cmnd *SCpnt; |
337 | struct request *rq = SCpnt->request; | 336 | struct scsi_device *sdp = q->queuedata; |
338 | struct gendisk *disk = rq->rq_disk; | 337 | struct gendisk *disk = rq->rq_disk; |
339 | sector_t block = rq->sector; | 338 | sector_t block = rq->sector; |
340 | unsigned int this_count = SCpnt->request_bufflen >> 9; | 339 | unsigned int this_count = rq->nr_sectors; |
341 | unsigned int timeout = sdp->timeout; | 340 | unsigned int timeout = sdp->timeout; |
341 | int ret; | ||
342 | |||
343 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
344 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
345 | goto out; | ||
346 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
347 | ret = BLKPREP_KILL; | ||
348 | goto out; | ||
349 | } | ||
350 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
351 | if (ret != BLKPREP_OK) | ||
352 | goto out; | ||
353 | SCpnt = rq->special; | ||
354 | |||
355 | /* from here on until we're complete, any goto out | ||
356 | * is used for a killable error condition */ | ||
357 | ret = BLKPREP_KILL; | ||
342 | 358 | ||
343 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, | 359 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, |
344 | "sd_init_command: block=%llu, " | 360 | "sd_init_command: block=%llu, " |
@@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
353 | rq->nr_sectors)); | 369 | rq->nr_sectors)); |
354 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 370 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
355 | "Retry with 0x%p\n", SCpnt)); | 371 | "Retry with 0x%p\n", SCpnt)); |
356 | return 0; | 372 | goto out; |
357 | } | 373 | } |
358 | 374 | ||
359 | if (sdp->changed) { | 375 | if (sdp->changed) { |
@@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
362 | * the changed bit has been reset | 378 | * the changed bit has been reset |
363 | */ | 379 | */ |
364 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ | 380 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ |
365 | return 0; | 381 | goto out; |
366 | } | 382 | } |
383 | |||
367 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", | 384 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", |
368 | (unsigned long long)block)); | 385 | (unsigned long long)block)); |
369 | 386 | ||
@@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
382 | if ((block & 1) || (rq->nr_sectors & 1)) { | 399 | if ((block & 1) || (rq->nr_sectors & 1)) { |
383 | scmd_printk(KERN_ERR, SCpnt, | 400 | scmd_printk(KERN_ERR, SCpnt, |
384 | "Bad block number requested\n"); | 401 | "Bad block number requested\n"); |
385 | return 0; | 402 | goto out; |
386 | } else { | 403 | } else { |
387 | block = block >> 1; | 404 | block = block >> 1; |
388 | this_count = this_count >> 1; | 405 | this_count = this_count >> 1; |
@@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
392 | if ((block & 3) || (rq->nr_sectors & 3)) { | 409 | if ((block & 3) || (rq->nr_sectors & 3)) { |
393 | scmd_printk(KERN_ERR, SCpnt, | 410 | scmd_printk(KERN_ERR, SCpnt, |
394 | "Bad block number requested\n"); | 411 | "Bad block number requested\n"); |
395 | return 0; | 412 | goto out; |
396 | } else { | 413 | } else { |
397 | block = block >> 2; | 414 | block = block >> 2; |
398 | this_count = this_count >> 2; | 415 | this_count = this_count >> 2; |
@@ -402,7 +419,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
402 | if ((block & 7) || (rq->nr_sectors & 7)) { | 419 | if ((block & 7) || (rq->nr_sectors & 7)) { |
403 | scmd_printk(KERN_ERR, SCpnt, | 420 | scmd_printk(KERN_ERR, SCpnt, |
404 | "Bad block number requested\n"); | 421 | "Bad block number requested\n"); |
405 | return 0; | 422 | goto out; |
406 | } else { | 423 | } else { |
407 | block = block >> 3; | 424 | block = block >> 3; |
408 | this_count = this_count >> 3; | 425 | this_count = this_count >> 3; |
@@ -410,7 +427,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
410 | } | 427 | } |
411 | if (rq_data_dir(rq) == WRITE) { | 428 | if (rq_data_dir(rq) == WRITE) { |
412 | if (!sdp->writeable) { | 429 | if (!sdp->writeable) { |
413 | return 0; | 430 | goto out; |
414 | } | 431 | } |
415 | SCpnt->cmnd[0] = WRITE_6; | 432 | SCpnt->cmnd[0] = WRITE_6; |
416 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 433 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
@@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
419 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 436 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
420 | } else { | 437 | } else { |
421 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); | 438 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); |
422 | return 0; | 439 | goto out; |
423 | } | 440 | } |
424 | 441 | ||
425 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 442 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
@@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
470 | */ | 487 | */ |
471 | scmd_printk(KERN_ERR, SCpnt, | 488 | scmd_printk(KERN_ERR, SCpnt, |
472 | "FUA write on READ/WRITE(6) drive\n"); | 489 | "FUA write on READ/WRITE(6) drive\n"); |
473 | return 0; | 490 | goto out; |
474 | } | 491 | } |
475 | 492 | ||
476 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); | 493 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); |
@@ -501,7 +518,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
501 | * This indicates that the command is ready from our end to be | 518 | * This indicates that the command is ready from our end to be |
502 | * queued. | 519 | * queued. |
503 | */ | 520 | */ |
504 | return 1; | 521 | ret = BLKPREP_OK; |
522 | out: | ||
523 | return scsi_prep_return(q, rq, ret); | ||
505 | } | 524 | } |
506 | 525 | ||
507 | /** | 526 | /** |
@@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev) | |||
1669 | 1688 | ||
1670 | sd_revalidate_disk(gd); | 1689 | sd_revalidate_disk(gd); |
1671 | 1690 | ||
1691 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | ||
1672 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); | 1692 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); |
1673 | 1693 | ||
1674 | gd->driverfs_dev = &sdp->sdev_gendev; | 1694 | gd->driverfs_dev = &sdp->sdev_gendev; |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 902eb11ffe8a..a0c4e13d4dab 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -78,7 +78,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); | |||
78 | 78 | ||
79 | static int sr_probe(struct device *); | 79 | static int sr_probe(struct device *); |
80 | static int sr_remove(struct device *); | 80 | static int sr_remove(struct device *); |
81 | static int sr_init_command(struct scsi_cmnd *); | ||
82 | 81 | ||
83 | static struct scsi_driver sr_template = { | 82 | static struct scsi_driver sr_template = { |
84 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
@@ -87,7 +86,6 @@ static struct scsi_driver sr_template = { | |||
87 | .probe = sr_probe, | 86 | .probe = sr_probe, |
88 | .remove = sr_remove, | 87 | .remove = sr_remove, |
89 | }, | 88 | }, |
90 | .init_command = sr_init_command, | ||
91 | }; | 89 | }; |
92 | 90 | ||
93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; | 91 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; |
@@ -296,19 +294,39 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
296 | scsi_io_completion(SCpnt, good_bytes); | 294 | scsi_io_completion(SCpnt, good_bytes); |
297 | } | 295 | } |
298 | 296 | ||
299 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 297 | static int sr_prep_fn(struct request_queue *q, struct request *rq) |
300 | { | 298 | { |
301 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; | 299 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; |
302 | struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); | 300 | struct scsi_cd *cd; |
301 | struct scsi_cmnd *SCpnt; | ||
302 | struct scsi_device *sdp = q->queuedata; | ||
303 | int ret; | ||
304 | |||
305 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
306 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
307 | goto out; | ||
308 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
309 | ret = BLKPREP_KILL; | ||
310 | goto out; | ||
311 | } | ||
312 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
313 | if (ret != BLKPREP_OK) | ||
314 | goto out; | ||
315 | SCpnt = rq->special; | ||
316 | cd = scsi_cd(rq->rq_disk); | ||
317 | |||
318 | /* from here on until we're complete, any goto out | ||
319 | * is used for a killable error condition */ | ||
320 | ret = BLKPREP_KILL; | ||
303 | 321 | ||
304 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", | 322 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", |
305 | cd->disk->disk_name, block)); | 323 | cd->disk->disk_name, block)); |
306 | 324 | ||
307 | if (!cd->device || !scsi_device_online(cd->device)) { | 325 | if (!cd->device || !scsi_device_online(cd->device)) { |
308 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", | 326 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", |
309 | SCpnt->request->nr_sectors)); | 327 | rq->nr_sectors)); |
310 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); | 328 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); |
311 | return 0; | 329 | goto out; |
312 | } | 330 | } |
313 | 331 | ||
314 | if (cd->device->changed) { | 332 | if (cd->device->changed) { |
@@ -316,7 +334,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
316 | * quietly refuse to do anything to a changed disc until the | 334 | * quietly refuse to do anything to a changed disc until the |
317 | * changed bit has been reset | 335 | * changed bit has been reset |
318 | */ | 336 | */ |
319 | return 0; | 337 | goto out; |
320 | } | 338 | } |
321 | 339 | ||
322 | /* | 340 | /* |
@@ -333,21 +351,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
333 | 351 | ||
334 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { | 352 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { |
335 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); | 353 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); |
336 | return 0; | 354 | goto out; |
337 | } | 355 | } |
338 | 356 | ||
339 | if (rq_data_dir(SCpnt->request) == WRITE) { | 357 | if (rq_data_dir(rq) == WRITE) { |
340 | if (!cd->device->writeable) | 358 | if (!cd->device->writeable) |
341 | return 0; | 359 | goto out; |
342 | SCpnt->cmnd[0] = WRITE_10; | 360 | SCpnt->cmnd[0] = WRITE_10; |
343 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 361 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
344 | cd->cdi.media_written = 1; | 362 | cd->cdi.media_written = 1; |
345 | } else if (rq_data_dir(SCpnt->request) == READ) { | 363 | } else if (rq_data_dir(rq) == READ) { |
346 | SCpnt->cmnd[0] = READ_10; | 364 | SCpnt->cmnd[0] = READ_10; |
347 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 365 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
348 | } else { | 366 | } else { |
349 | blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); | 367 | blk_dump_rq_flags(rq, "Unknown sr command"); |
350 | return 0; | 368 | goto out; |
351 | } | 369 | } |
352 | 370 | ||
353 | { | 371 | { |
@@ -368,10 +386,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
368 | /* | 386 | /* |
369 | * request doesn't start on hw block boundary, add scatter pads | 387 | * request doesn't start on hw block boundary, add scatter pads |
370 | */ | 388 | */ |
371 | if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || | 389 | if (((unsigned int)rq->sector % (s_size >> 9)) || |
372 | (SCpnt->request_bufflen % s_size)) { | 390 | (SCpnt->request_bufflen % s_size)) { |
373 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); | 391 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); |
374 | return 0; | 392 | goto out; |
375 | } | 393 | } |
376 | 394 | ||
377 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); | 395 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); |
@@ -379,12 +397,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
379 | 397 | ||
380 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", | 398 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", |
381 | cd->cdi.name, | 399 | cd->cdi.name, |
382 | (rq_data_dir(SCpnt->request) == WRITE) ? | 400 | (rq_data_dir(rq) == WRITE) ? |
383 | "writing" : "reading", | 401 | "writing" : "reading", |
384 | this_count, SCpnt->request->nr_sectors)); | 402 | this_count, rq->nr_sectors)); |
385 | 403 | ||
386 | SCpnt->cmnd[1] = 0; | 404 | SCpnt->cmnd[1] = 0; |
387 | block = (unsigned int)SCpnt->request->sector / (s_size >> 9); | 405 | block = (unsigned int)rq->sector / (s_size >> 9); |
388 | 406 | ||
389 | if (this_count > 0xffff) { | 407 | if (this_count > 0xffff) { |
390 | this_count = 0xffff; | 408 | this_count = 0xffff; |
@@ -419,7 +437,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
419 | * This indicates that the command is ready from our end to be | 437 | * This indicates that the command is ready from our end to be |
420 | * queued. | 438 | * queued. |
421 | */ | 439 | */ |
422 | return 1; | 440 | ret = BLKPREP_OK; |
441 | out: | ||
442 | return scsi_prep_return(q, rq, ret); | ||
423 | } | 443 | } |
424 | 444 | ||
425 | static int sr_block_open(struct inode *inode, struct file *file) | 445 | static int sr_block_open(struct inode *inode, struct file *file) |
@@ -590,6 +610,7 @@ static int sr_probe(struct device *dev) | |||
590 | 610 | ||
591 | /* FIXME: need to handle a get_capabilities failure properly ?? */ | 611 | /* FIXME: need to handle a get_capabilities failure properly ?? */ |
592 | get_capabilities(cd); | 612 | get_capabilities(cd); |
613 | blk_queue_prep_rq(sdev->request_queue, sr_prep_fn); | ||
593 | sr_vendor_init(cd); | 614 | sr_vendor_init(cd); |
594 | 615 | ||
595 | disk->driverfs_dev = &sdev->sdev_gendev; | 616 | disk->driverfs_dev = &sdev->sdev_gendev; |
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 3465f31a21c4..56a304709fde 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h | |||
@@ -5,13 +5,15 @@ | |||
5 | 5 | ||
6 | struct module; | 6 | struct module; |
7 | struct scsi_cmnd; | 7 | struct scsi_cmnd; |
8 | struct scsi_device; | ||
9 | struct request; | ||
10 | struct request_queue; | ||
8 | 11 | ||
9 | 12 | ||
10 | struct scsi_driver { | 13 | struct scsi_driver { |
11 | struct module *owner; | 14 | struct module *owner; |
12 | struct device_driver gendrv; | 15 | struct device_driver gendrv; |
13 | 16 | ||
14 | int (*init_command)(struct scsi_cmnd *); | ||
15 | void (*rescan)(struct device *); | 17 | void (*rescan)(struct device *); |
16 | }; | 18 | }; |
17 | #define to_scsi_driver(drv) \ | 19 | #define to_scsi_driver(drv) \ |
@@ -25,4 +27,9 @@ extern int scsi_register_interface(struct class_interface *); | |||
25 | #define scsi_unregister_interface(intf) \ | 27 | #define scsi_unregister_interface(intf) \ |
26 | class_interface_unregister(intf) | 28 | class_interface_unregister(intf) |
27 | 29 | ||
30 | int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); | ||
31 | int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); | ||
32 | int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); | ||
33 | int scsi_prep_return(struct request_queue *q, struct request *req, int ret); | ||
34 | |||
28 | #endif /* _SCSI_SCSI_DRIVER_H */ | 35 | #endif /* _SCSI_SCSI_DRIVER_H */ |
diff --git a/include/scsi/sd.h b/include/scsi/sd.h index ce02ad1f5185..aa1e71613010 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h | |||
@@ -55,7 +55,6 @@ static void sd_shutdown(struct device *dev); | |||
55 | static int sd_suspend(struct device *dev, pm_message_t state); | 55 | static int sd_suspend(struct device *dev, pm_message_t state); |
56 | static int sd_resume(struct device *dev); | 56 | static int sd_resume(struct device *dev); |
57 | static void sd_rescan(struct device *); | 57 | static void sd_rescan(struct device *); |
58 | static int sd_init_command(struct scsi_cmnd *); | ||
59 | static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); | 58 | static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); |
60 | static void scsi_disk_release(struct class_device *cdev); | 59 | static void scsi_disk_release(struct class_device *cdev); |
61 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | 60 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); |