diff options
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); |
