Commit 30c633b8 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ide-cd error handling oops fix

cdrom_decode_status() can call cdrom_end_request() twice.  The second call
oopses because the first call destroyed the request.

Fix it to only call cdrom_end_request() once.

Jens has acked this change.
parent 8a8f9d8e
...@@ -765,10 +765,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ...@@ -765,10 +765,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
if ((stat & ERR_STAT) != 0) if ((stat & ERR_STAT) != 0)
cdrom_queue_request_sense(drive, wait, rq->sense, rq); cdrom_queue_request_sense(drive, wait, rq->sense, rq);
} else if (blk_fs_request(rq)) { } else if (blk_fs_request(rq)) {
int do_end_request = 0;
/* Handle errors from READ and WRITE requests. */ /* Handle errors from READ and WRITE requests. */
if (blk_noretry_request(rq)) if (blk_noretry_request(rq))
cdrom_end_request(drive, 0); do_end_request = 1;
if (sense_key == NOT_READY) { if (sense_key == NOT_READY) {
/* Tray open. */ /* Tray open. */
...@@ -776,7 +778,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ...@@ -776,7 +778,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
/* Fail the request. */ /* Fail the request. */
printk ("%s: tray open\n", drive->name); printk ("%s: tray open\n", drive->name);
cdrom_end_request(drive, 0); do_end_request = 1;
} else if (sense_key == UNIT_ATTENTION) { } else if (sense_key == UNIT_ATTENTION) {
/* Media change. */ /* Media change. */
cdrom_saw_media_change (drive); cdrom_saw_media_change (drive);
...@@ -785,13 +787,13 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ...@@ -785,13 +787,13 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
But be sure to give up if we've retried But be sure to give up if we've retried
too many times. */ too many times. */
if (++rq->errors > ERROR_MAX) if (++rq->errors > ERROR_MAX)
cdrom_end_request(drive, 0); do_end_request = 1;
} else if (sense_key == ILLEGAL_REQUEST || } else if (sense_key == ILLEGAL_REQUEST ||
sense_key == DATA_PROTECT) { sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal /* No point in retrying after an illegal
request or data protect error.*/ request or data protect error.*/
ide_dump_status (drive, "command error", stat); ide_dump_status (drive, "command error", stat);
cdrom_end_request(drive, 0); do_end_request = 1;
} else if ((err & ~ABRT_ERR) != 0) { } else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler /* Go to the default handler
for other errors. */ for other errors. */
...@@ -801,12 +803,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ...@@ -801,12 +803,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
/* No point in re-trying a zillion times on a bad /* No point in re-trying a zillion times on a bad
* sector... If we got here the error is not correctable */ * sector... If we got here the error is not correctable */
ide_dump_status (drive, "media error (bad sector)", stat); ide_dump_status (drive, "media error (bad sector)", stat);
cdrom_end_request(drive, 0); do_end_request = 1;
} else if ((++rq->errors > ERROR_MAX)) { } else if ((++rq->errors > ERROR_MAX)) {
/* We've racked up too many retries. Abort. */ /* We've racked up too many retries. Abort. */
cdrom_end_request(drive, 0); do_end_request = 1;
} }
if (do_end_request)
cdrom_end_request(drive, 0);
/* If we got a CHECK_CONDITION status, /* If we got a CHECK_CONDITION status,
queue a request sense command. */ queue a request sense command. */
if ((stat & ERR_STAT) != 0) if ((stat & ERR_STAT) != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment