diff options
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 59 |
1 files changed, 40 insertions, 19 deletions
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; |