diff options
| author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-26 15:50:35 -0500 |
|---|---|---|
| committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-26 15:50:35 -0500 |
| commit | 9f10d9ee0ac6d79d7bc8b9a158bf4a29322d84d3 (patch) | |
| tree | 81a2bd142a2f3e2923df308f6e835b8d905a8cde | |
| parent | 788d669736dd3d15195fea07bf97ec5a2e9f15e7 (diff) | |
ide-cd: fix 'ireason' handling for REQ_TYPE_ATA_PC requests
Pass 'struct request *rq' to ide_cd_check_ireason() from cdrom_newpc_intr()
and use ide_cd_check_ireason() also for REQ_TYPE_ATA_PC requests.
This fixes some hangs caused by not finishing the transfer before ending
the request and also makes use of 'ireason == 1' quirk for spurious IRQs.
Tested-by: Brad Rosser <brad.rosser@gmail.com>
Cc: Borislav Petkov <petkovbb@googlemail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
| -rw-r--r-- | drivers/ide/ide-cd.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 022a029f81c2..1495fe7a6ecf 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, | |||
| 670 | * and attempt to recover if there are problems. Returns 0 if everything's | 670 | * and attempt to recover if there are problems. Returns 0 if everything's |
| 671 | * ok; nonzero if the request has been terminated. | 671 | * ok; nonzero if the request has been terminated. |
| 672 | */ | 672 | */ |
| 673 | static | 673 | static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, |
| 674 | int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) | 674 | int len, int ireason, int rw) |
| 675 | { | 675 | { |
| 676 | /* | 676 | /* |
| 677 | * ireason == 0: the drive wants to receive data from us | 677 | * ireason == 0: the drive wants to receive data from us |
| @@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) | |||
| 701 | drive->name, __FUNCTION__, ireason); | 701 | drive->name, __FUNCTION__, ireason); |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | ||
| 705 | rq->cmd_flags |= REQ_FAILED; | ||
| 706 | |||
| 704 | cdrom_end_request(drive, 0); | 707 | cdrom_end_request(drive, 0); |
| 705 | return -1; | 708 | return -1; |
| 706 | } | 709 | } |
| @@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 1071 | /* | 1074 | /* |
| 1072 | * check which way to transfer data | 1075 | * check which way to transfer data |
| 1073 | */ | 1076 | */ |
| 1074 | if (blk_fs_request(rq) || blk_pc_request(rq)) { | 1077 | if (ide_cd_check_ireason(drive, rq, len, ireason, write)) |
| 1075 | if (ide_cd_check_ireason(drive, len, ireason, write)) | 1078 | return ide_stopped; |
| 1076 | return ide_stopped; | ||
| 1077 | 1079 | ||
| 1078 | if (blk_fs_request(rq) && write == 0) { | 1080 | if (blk_fs_request(rq)) { |
| 1081 | if (write == 0) { | ||
| 1079 | int nskip; | 1082 | int nskip; |
| 1080 | 1083 | ||
| 1081 | if (ide_cd_check_transfer_size(drive, len)) { | 1084 | if (ide_cd_check_transfer_size(drive, len)) { |
| @@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 1101 | if (ireason == 0) { | 1104 | if (ireason == 0) { |
| 1102 | write = 1; | 1105 | write = 1; |
| 1103 | xferfunc = HWIF(drive)->atapi_output_bytes; | 1106 | xferfunc = HWIF(drive)->atapi_output_bytes; |
| 1104 | } else if (ireason == 2 || (ireason == 1 && | 1107 | } else { |
| 1105 | (blk_fs_request(rq) || blk_pc_request(rq)))) { | ||
| 1106 | write = 0; | 1108 | write = 0; |
| 1107 | xferfunc = HWIF(drive)->atapi_input_bytes; | 1109 | xferfunc = HWIF(drive)->atapi_input_bytes; |
| 1108 | } else { | ||
| 1109 | printk(KERN_ERR "%s: %s: The drive " | ||
| 1110 | "appears confused (ireason = 0x%02x). " | ||
| 1111 | "Trying to recover by ending request.\n", | ||
| 1112 | drive->name, __FUNCTION__, ireason); | ||
| 1113 | goto end_request; | ||
| 1114 | } | 1110 | } |
| 1115 | 1111 | ||
| 1116 | /* | 1112 | /* |
