aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-20 13:11:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-20 13:11:11 -0400
commite6423407d01168f7760cdee7270d9f51d1240301 (patch)
tree979795cfa8f6946238ab31f544159142f3e7df93 /drivers/ide/ide-cd.c
parent7f8189068726492950bf1a2dcfd9b51314560abf (diff)
parent39c58f37a10198054c656c28202fb1e6d22fd505 (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.c78
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
95static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, 95static 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
142static void cdrom_analyze_sense_data(ide_drive_t *drive, 142static 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 */
418static 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
457static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) 412static 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);