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>
This commit is contained in:
parent
788d669736
commit
9f10d9ee0a
|
@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
|
||||||
* and attempt to recover if there are problems. Returns 0 if everything's
|
* and attempt to recover if there are problems. Returns 0 if everything's
|
||||||
* ok; nonzero if the request has been terminated.
|
* ok; nonzero if the request has been terminated.
|
||||||
*/
|
*/
|
||||||
static
|
static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
|
||||||
int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
|
int len, int ireason, int rw)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* ireason == 0: the drive wants to receive data from us
|
* 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)
|
||||||
drive->name, __FUNCTION__, ireason);
|
drive->name, __FUNCTION__, ireason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rq->cmd_type == REQ_TYPE_ATA_PC)
|
||||||
|
rq->cmd_flags |= REQ_FAILED;
|
||||||
|
|
||||||
cdrom_end_request(drive, 0);
|
cdrom_end_request(drive, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
|
||||||
/*
|
/*
|
||||||
* check which way to transfer data
|
* check which way to transfer data
|
||||||
*/
|
*/
|
||||||
if (blk_fs_request(rq) || blk_pc_request(rq)) {
|
if (ide_cd_check_ireason(drive, rq, len, ireason, write))
|
||||||
if (ide_cd_check_ireason(drive, len, ireason, write))
|
return ide_stopped;
|
||||||
return ide_stopped;
|
|
||||||
|
|
||||||
if (blk_fs_request(rq) && write == 0) {
|
if (blk_fs_request(rq)) {
|
||||||
|
if (write == 0) {
|
||||||
int nskip;
|
int nskip;
|
||||||
|
|
||||||
if (ide_cd_check_transfer_size(drive, len)) {
|
if (ide_cd_check_transfer_size(drive, len)) {
|
||||||
|
@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
|
||||||
if (ireason == 0) {
|
if (ireason == 0) {
|
||||||
write = 1;
|
write = 1;
|
||||||
xferfunc = HWIF(drive)->atapi_output_bytes;
|
xferfunc = HWIF(drive)->atapi_output_bytes;
|
||||||
} else if (ireason == 2 || (ireason == 1 &&
|
} else {
|
||||||
(blk_fs_request(rq) || blk_pc_request(rq)))) {
|
|
||||||
write = 0;
|
write = 0;
|
||||||
xferfunc = HWIF(drive)->atapi_input_bytes;
|
xferfunc = HWIF(drive)->atapi_input_bytes;
|
||||||
} else {
|
|
||||||
printk(KERN_ERR "%s: %s: The drive "
|
|
||||||
"appears confused (ireason = 0x%02x). "
|
|
||||||
"Trying to recover by ending request.\n",
|
|
||||||
drive->name, __FUNCTION__, ireason);
|
|
||||||
goto end_request;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue