diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 11:19:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 11:19:33 -0400 |
commit | df3d80f5a5c74168be42788364d13cf6c83c7b9c (patch) | |
tree | 892a964c2fd28d028f2fb7471e8543d3f4006a58 /drivers/scsi/sr.c | |
parent | 3d06f7a5f74a813cee817c4b30b5e6f0398da0be (diff) | |
parent | c8e91b0a8fc8493e3bf3efcb3c8f866e9453cf1c (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (207 commits)
[SCSI] gdth: fix CONFIG_ISA build failure
[SCSI] esp_scsi: remove __dev{init,exit}
[SCSI] gdth: !use_sg cleanup and use of scsi accessors
[SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2
[SCSI] gdth: Setup proper per-command private data
[SCSI] gdth: Remove gdth_ctr_tab[]
[SCSI] gdth: switch to modern scsi host registration
[SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes
[SCSI] gdth: clean up host private data
[SCSI] gdth: Remove virt hosts
[SCSI] gdth: Reorder scsi_host_template intitializers
[SCSI] gdth: kill gdth_{read,write}[bwl] wrappers
[SCSI] gdth: Remove 2.4.x support, in-kernel changelog
[SCSI] gdth: split out pci probing
[SCSI] gdth: split out eisa probing
[SCSI] gdth: split out isa probing
gdth: Make one abuse of scsi_cmnd less obvious
[SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation
[SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution
[SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE
...
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r-- | drivers/scsi/sr.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 902eb11ffe8a..c61999031141 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -78,7 +78,7 @@ 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 *); | 81 | static int sr_done(struct scsi_cmnd *); |
82 | 82 | ||
83 | static struct scsi_driver sr_template = { | 83 | static struct scsi_driver sr_template = { |
84 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
@@ -87,7 +87,7 @@ static struct scsi_driver sr_template = { | |||
87 | .probe = sr_probe, | 87 | .probe = sr_probe, |
88 | .remove = sr_remove, | 88 | .remove = sr_remove, |
89 | }, | 89 | }, |
90 | .init_command = sr_init_command, | 90 | .done = sr_done, |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; | 93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; |
@@ -210,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * rw_intr is the interrupt routine for the device driver. | 213 | * sr_done is the interrupt routine for the device driver. |
214 | * | 214 | * |
215 | * It will be notified on the end of a SCSI read / write, and will take on | 215 | * It will be notified on the end of a SCSI read / write, and will take one |
216 | * of several actions based on success or failure. | 216 | * of several actions based on success or failure. |
217 | */ | 217 | */ |
218 | static void rw_intr(struct scsi_cmnd * SCpnt) | 218 | static int sr_done(struct scsi_cmnd *SCpnt) |
219 | { | 219 | { |
220 | int result = SCpnt->result; | 220 | int result = SCpnt->result; |
221 | int this_count = SCpnt->request_bufflen; | 221 | int this_count = SCpnt->request_bufflen; |
@@ -288,27 +288,42 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
288 | } | 288 | } |
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | return good_bytes; |
292 | * This calls the generic completion function, now that we know | ||
293 | * how many actual sectors finished, and how many sectors we need | ||
294 | * to say have failed. | ||
295 | */ | ||
296 | scsi_io_completion(SCpnt, good_bytes); | ||
297 | } | 292 | } |
298 | 293 | ||
299 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 294 | static int sr_prep_fn(struct request_queue *q, struct request *rq) |
300 | { | 295 | { |
301 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; | 296 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; |
302 | struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); | 297 | struct scsi_cd *cd; |
298 | struct scsi_cmnd *SCpnt; | ||
299 | struct scsi_device *sdp = q->queuedata; | ||
300 | int ret; | ||
301 | |||
302 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
303 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
304 | goto out; | ||
305 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
306 | ret = BLKPREP_KILL; | ||
307 | goto out; | ||
308 | } | ||
309 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
310 | if (ret != BLKPREP_OK) | ||
311 | goto out; | ||
312 | SCpnt = rq->special; | ||
313 | cd = scsi_cd(rq->rq_disk); | ||
314 | |||
315 | /* from here on until we're complete, any goto out | ||
316 | * is used for a killable error condition */ | ||
317 | ret = BLKPREP_KILL; | ||
303 | 318 | ||
304 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", | 319 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", |
305 | cd->disk->disk_name, block)); | 320 | cd->disk->disk_name, block)); |
306 | 321 | ||
307 | if (!cd->device || !scsi_device_online(cd->device)) { | 322 | if (!cd->device || !scsi_device_online(cd->device)) { |
308 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", | 323 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", |
309 | SCpnt->request->nr_sectors)); | 324 | rq->nr_sectors)); |
310 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); | 325 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); |
311 | return 0; | 326 | goto out; |
312 | } | 327 | } |
313 | 328 | ||
314 | if (cd->device->changed) { | 329 | if (cd->device->changed) { |
@@ -316,7 +331,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
316 | * quietly refuse to do anything to a changed disc until the | 331 | * quietly refuse to do anything to a changed disc until the |
317 | * changed bit has been reset | 332 | * changed bit has been reset |
318 | */ | 333 | */ |
319 | return 0; | 334 | goto out; |
320 | } | 335 | } |
321 | 336 | ||
322 | /* | 337 | /* |
@@ -333,21 +348,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
333 | 348 | ||
334 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { | 349 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { |
335 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); | 350 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); |
336 | return 0; | 351 | goto out; |
337 | } | 352 | } |
338 | 353 | ||
339 | if (rq_data_dir(SCpnt->request) == WRITE) { | 354 | if (rq_data_dir(rq) == WRITE) { |
340 | if (!cd->device->writeable) | 355 | if (!cd->device->writeable) |
341 | return 0; | 356 | goto out; |
342 | SCpnt->cmnd[0] = WRITE_10; | 357 | SCpnt->cmnd[0] = WRITE_10; |
343 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 358 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
344 | cd->cdi.media_written = 1; | 359 | cd->cdi.media_written = 1; |
345 | } else if (rq_data_dir(SCpnt->request) == READ) { | 360 | } else if (rq_data_dir(rq) == READ) { |
346 | SCpnt->cmnd[0] = READ_10; | 361 | SCpnt->cmnd[0] = READ_10; |
347 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 362 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
348 | } else { | 363 | } else { |
349 | blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); | 364 | blk_dump_rq_flags(rq, "Unknown sr command"); |
350 | return 0; | 365 | goto out; |
351 | } | 366 | } |
352 | 367 | ||
353 | { | 368 | { |
@@ -368,10 +383,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
368 | /* | 383 | /* |
369 | * request doesn't start on hw block boundary, add scatter pads | 384 | * request doesn't start on hw block boundary, add scatter pads |
370 | */ | 385 | */ |
371 | if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || | 386 | if (((unsigned int)rq->sector % (s_size >> 9)) || |
372 | (SCpnt->request_bufflen % s_size)) { | 387 | (SCpnt->request_bufflen % s_size)) { |
373 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); | 388 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); |
374 | return 0; | 389 | goto out; |
375 | } | 390 | } |
376 | 391 | ||
377 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); | 392 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); |
@@ -379,12 +394,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
379 | 394 | ||
380 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", | 395 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", |
381 | cd->cdi.name, | 396 | cd->cdi.name, |
382 | (rq_data_dir(SCpnt->request) == WRITE) ? | 397 | (rq_data_dir(rq) == WRITE) ? |
383 | "writing" : "reading", | 398 | "writing" : "reading", |
384 | this_count, SCpnt->request->nr_sectors)); | 399 | this_count, rq->nr_sectors)); |
385 | 400 | ||
386 | SCpnt->cmnd[1] = 0; | 401 | SCpnt->cmnd[1] = 0; |
387 | block = (unsigned int)SCpnt->request->sector / (s_size >> 9); | 402 | block = (unsigned int)rq->sector / (s_size >> 9); |
388 | 403 | ||
389 | if (this_count > 0xffff) { | 404 | if (this_count > 0xffff) { |
390 | this_count = 0xffff; | 405 | this_count = 0xffff; |
@@ -410,16 +425,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
410 | SCpnt->timeout_per_command = timeout; | 425 | SCpnt->timeout_per_command = timeout; |
411 | 426 | ||
412 | /* | 427 | /* |
413 | * This is the completion routine we use. This is matched in terms | ||
414 | * of capability to this function. | ||
415 | */ | ||
416 | SCpnt->done = rw_intr; | ||
417 | |||
418 | /* | ||
419 | * This indicates that the command is ready from our end to be | 428 | * This indicates that the command is ready from our end to be |
420 | * queued. | 429 | * queued. |
421 | */ | 430 | */ |
422 | return 1; | 431 | ret = BLKPREP_OK; |
432 | out: | ||
433 | return scsi_prep_return(q, rq, ret); | ||
423 | } | 434 | } |
424 | 435 | ||
425 | static int sr_block_open(struct inode *inode, struct file *file) | 436 | static int sr_block_open(struct inode *inode, struct file *file) |
@@ -590,6 +601,7 @@ static int sr_probe(struct device *dev) | |||
590 | 601 | ||
591 | /* FIXME: need to handle a get_capabilities failure properly ?? */ | 602 | /* FIXME: need to handle a get_capabilities failure properly ?? */ |
592 | get_capabilities(cd); | 603 | get_capabilities(cd); |
604 | blk_queue_prep_rq(sdev->request_queue, sr_prep_fn); | ||
593 | sr_vendor_init(cd); | 605 | sr_vendor_init(cd); |
594 | 606 | ||
595 | disk->driverfs_dev = &sdev->sdev_gendev; | 607 | disk->driverfs_dev = &sdev->sdev_gendev; |