diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-20 13:11:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-20 13:11:11 -0400 |
commit | e6423407d01168f7760cdee7270d9f51d1240301 (patch) | |
tree | 979795cfa8f6946238ab31f544159142f3e7df93 /drivers/ide/ide-cd.c | |
parent | 7f8189068726492950bf1a2dcfd9b51314560abf (diff) | |
parent | 39c58f37a10198054c656c28202fb1e6d22fd505 (diff) |
Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (34 commits)
ide-cd: prevent null pointer deref via cdrom_newpc_intr
ide: BUG() on unknown requests
ide: filter out invalid DMA xfer mode changes in HDIO_DRIVE_CMD ioctl handler
ide: do not access ide_drive_t 'drive_data' field directly
sl82c105: implement test_irq() method
siimage: implement test_irq() method
pdc202xx_old: implement test_irq() method (take 2)
cmd64x: implement test_irq() method
cmd640: implement test_irq() method
ide: move ack_intr() method into 'struct ide_port_ops' (take 2)
ide: move IRQ clearing from ack_intr() method to clear_irq() method (take 2)
siimage: use ide_dma_test_irq() (take 2)
cmd64x: implement clear_irq() method (take 2)
ide: call clear_irq() method in ide_timer_expiry()
sgiioc4: coding style cleanup
ide: don't enable IORDY at a probe time
ide: IORDY handling fixes
ata: add ata_id_pio_need_iordy() helper (v2)
ide-tape: fix build issue
ide: unify interrupt reason checking
...
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 78 |
1 files changed, 14 insertions, 64 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 424140c6c400..4a19686fcfe9 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -92,16 +92,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive) | |||
92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; | 92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; |
93 | } | 93 | } |
94 | 94 | ||
95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | 95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq) |
96 | struct request_sense *sense) | ||
97 | { | 96 | { |
97 | struct request_sense *sense = &drive->sense_data; | ||
98 | int log = 0; | 98 | int log = 0; |
99 | 99 | ||
100 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); | ||
101 | |||
102 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) | 100 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) |
103 | return 0; | 101 | return 0; |
104 | 102 | ||
103 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); | ||
104 | |||
105 | switch (sense->sense_key) { | 105 | switch (sense->sense_key) { |
106 | case NO_SENSE: | 106 | case NO_SENSE: |
107 | case RECOVERED_ERROR: | 107 | case RECOVERED_ERROR: |
@@ -140,12 +140,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | |||
140 | } | 140 | } |
141 | 141 | ||
142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, | 142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, |
143 | struct request *failed_command, | 143 | struct request *failed_command) |
144 | struct request_sense *sense) | ||
145 | { | 144 | { |
145 | struct request_sense *sense = &drive->sense_data; | ||
146 | struct cdrom_info *info = drive->driver_data; | ||
146 | unsigned long sector; | 147 | unsigned long sector; |
147 | unsigned long bio_sectors; | 148 | unsigned long bio_sectors; |
148 | struct cdrom_info *info = drive->driver_data; | ||
149 | 149 | ||
150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", | 150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", |
151 | sense->error_code, sense->sense_key); | 151 | sense->error_code, sense->sense_key); |
@@ -154,7 +154,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", | 154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", |
155 | failed_command->cmd[0]); | 155 | failed_command->cmd[0]); |
156 | 156 | ||
157 | if (!cdrom_log_sense(drive, failed_command, sense)) | 157 | if (!cdrom_log_sense(drive, failed_command)) |
158 | return; | 158 | return; |
159 | 159 | ||
160 | /* | 160 | /* |
@@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | |||
225 | * sense pointer set. | 225 | * sense pointer set. |
226 | */ | 226 | */ |
227 | memcpy(failed->sense, sense, 18); | 227 | memcpy(failed->sense, sense, 18); |
228 | sense = failed->sense; | ||
229 | failed->sense_len = rq->sense_len; | 228 | failed->sense_len = rq->sense_len; |
230 | } | 229 | } |
231 | cdrom_analyze_sense_data(drive, failed, sense); | 230 | cdrom_analyze_sense_data(drive, failed); |
232 | 231 | ||
233 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) | 232 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) |
234 | BUG(); | 233 | BUG(); |
235 | } else | 234 | } else |
236 | cdrom_analyze_sense_data(drive, NULL, sense); | 235 | cdrom_analyze_sense_data(drive, NULL); |
237 | } | 236 | } |
238 | 237 | ||
239 | 238 | ||
@@ -410,50 +409,6 @@ end_request: | |||
410 | return 2; | 409 | return 2; |
411 | } | 410 | } |
412 | 411 | ||
413 | /* | ||
414 | * Check the contents of the interrupt reason register from the cdrom | ||
415 | * and attempt to recover if there are problems. Returns 0 if everything's | ||
416 | * ok; nonzero if the request has been terminated. | ||
417 | */ | ||
418 | static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | ||
419 | int len, int ireason, int rw) | ||
420 | { | ||
421 | ide_hwif_t *hwif = drive->hwif; | ||
422 | |||
423 | ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); | ||
424 | |||
425 | /* | ||
426 | * ireason == 0: the drive wants to receive data from us | ||
427 | * ireason == 2: the drive is expecting to transfer data to us | ||
428 | */ | ||
429 | if (ireason == (!rw << 1)) | ||
430 | return 0; | ||
431 | else if (ireason == (rw << 1)) { | ||
432 | |||
433 | /* whoops... */ | ||
434 | printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", | ||
435 | drive->name, __func__); | ||
436 | |||
437 | ide_pad_transfer(drive, rw, len); | ||
438 | } else if (rw == 0 && ireason == 1) { | ||
439 | /* | ||
440 | * Some drives (ASUS) seem to tell us that status info is | ||
441 | * available. Just get it and ignore. | ||
442 | */ | ||
443 | (void)hwif->tp_ops->read_status(hwif); | ||
444 | return 0; | ||
445 | } else { | ||
446 | /* drive wants a command packet, or invalid ireason... */ | ||
447 | printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", | ||
448 | drive->name, __func__, ireason); | ||
449 | } | ||
450 | |||
451 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | ||
452 | rq->cmd_flags |= REQ_FAILED; | ||
453 | |||
454 | return -1; | ||
455 | } | ||
456 | |||
457 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) | 412 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) |
458 | { | 413 | { |
459 | struct request *rq = cmd->rq; | 414 | struct request *rq = cmd->rq; |
@@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
645 | goto out_end; | 600 | goto out_end; |
646 | } | 601 | } |
647 | 602 | ||
648 | /* check which way to transfer data */ | 603 | rc = ide_check_ireason(drive, rq, len, ireason, write); |
649 | rc = ide_cd_check_ireason(drive, rq, len, ireason, write); | ||
650 | if (rc) | 604 | if (rc) |
651 | goto out_end; | 605 | goto out_end; |
652 | 606 | ||
@@ -713,7 +667,7 @@ out_end: | |||
713 | rq->errors = -EIO; | 667 | rq->errors = -EIO; |
714 | } | 668 | } |
715 | 669 | ||
716 | if (uptodate == 0) | 670 | if (uptodate == 0 && rq->bio) |
717 | ide_cd_error_cmd(drive, cmd); | 671 | ide_cd_error_cmd(drive, cmd); |
718 | 672 | ||
719 | /* make sure it's fully ended */ | 673 | /* make sure it's fully ended */ |
@@ -831,12 +785,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
831 | /* right now this can only be a reset... */ | 785 | /* right now this can only be a reset... */ |
832 | uptodate = 1; | 786 | uptodate = 1; |
833 | goto out_end; | 787 | goto out_end; |
834 | } else { | 788 | } else |
835 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); | 789 | BUG(); |
836 | if (rq->errors == 0) | ||
837 | rq->errors = -EIO; | ||
838 | goto out_end; | ||
839 | } | ||
840 | 790 | ||
841 | /* prepare sense request for this command */ | 791 | /* prepare sense request for this command */ |
842 | ide_prep_sense(drive, rq); | 792 | ide_prep_sense(drive, rq); |