From 8e59bfde31e69fb1f630ec0efd24a50c5a51b0bf Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 8 Apr 2009 14:12:51 +0200 Subject: ide-cd: move status checking into the IRQ handler There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 35729a47f797..a4afd9082c4a 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -271,29 +271,18 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) * 1: if the request will be going through error recovery. * 2: if the request should be ended. */ -static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) +static int cdrom_decode_status(ide_drive_t *drive, u8 stat) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; - int stat, err, sense_key; - - /* check for errors */ - stat = hwif->tp_ops->read_status(hwif); - - if (stat_ret) - *stat_ret = stat; - - if (OK_STAT(stat, good_stat, BAD_R_STAT)) - return 0; + int err, sense_key; /* get the IDE error register */ err = ide_read_error(drive); sense_key = err >> 4; - ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " - "rq->cmd_type: 0x%x, err: 0x%x", - stat, good_stat, rq->cmd[0], rq->cmd_type, - err); + ide_debug_log(IDE_DBG_RQ, "cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x", + rq->cmd[0], rq->cmd_type, err); if (blk_sense_request(rq)) { /* @@ -624,12 +613,12 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; ide_expiry_t *expiry = NULL; - int dma_error = 0, dma, stat, thislen, uptodate = 0; + int dma_error = 0, dma, thislen, uptodate = 0; int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; int sense = blk_sense_request(rq); unsigned int timeout; u16 len; - u8 ireason; + u8 ireason, stat; ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", rq->cmd[0], write); @@ -648,11 +637,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } - rc = cdrom_decode_status(drive, 0, &stat); - if (rc) { - if (rc == 2) - goto out_end; - return ide_stopped; + /* check status */ + stat = hwif->tp_ops->read_status(hwif); + + if (!OK_STAT(stat, 0, BAD_R_STAT)) { + rc = cdrom_decode_status(drive, stat); + if (rc) { + if (rc == 2) + goto out_end; + return ide_stopped; + } } /* using dma, transfer is complete now */ -- cgit v1.2.2 From 805ec58ad7fd1f65eeb75ed38f11bd08fbd3b988 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 8 Apr 2009 14:12:52 +0200 Subject: ide-cd: carve out an ide_cd_breathe()-helper for fs write requests There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 65 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 27 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index a4afd9082c4a..7bbdeb7e3bc4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -265,7 +265,43 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) cdrom_analyze_sense_data(drive, NULL, sense); } + /* + * Allow the drive 5 seconds to recover; some devices will return NOT_READY + * while flushing data from cache. + * + * returns: 0 failed (write timeout expired) + * 1 success + */ +static int ide_cd_breathe(ide_drive_t *drive, struct request *rq) +{ + + struct cdrom_info *info = drive->driver_data; + + if (!rq->errors) + info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; + + rq->errors = 1; + + if (time_after(jiffies, info->write_timeout)) + return 0; + else { + struct request_queue *q = drive->queue; + unsigned long flags; + + /* + * take a breather relying on the unplug timer to kick us again + */ + + spin_lock_irqsave(q->queue_lock, flags); + blk_plug_device(q); + spin_unlock_irqrestore(q->queue_lock, flags); + + return 1; + } +} + +/** * Returns: * 0: if the request should be continued. * 1: if the request will be going through error recovery. @@ -348,36 +384,11 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) /* fail the request */ printk(KERN_ERR PFX "%s: tray open\n", drive->name); - do_end_request = 1; } else { - struct cdrom_info *info = drive->driver_data; - - /* - * Allow the drive 5 seconds to recover, some - * devices will return this error while flushing - * data from cache. - */ - if (!rq->errors) - info->write_timeout = jiffies + - ATAPI_WAIT_WRITE_BUSY; - rq->errors = 1; - if (time_after(jiffies, info->write_timeout)) - do_end_request = 1; - else { - struct request_queue *q = drive->queue; - unsigned long flags; - - /* - * take a breather relying on the unplug - * timer to kick us again - */ - spin_lock_irqsave(q->queue_lock, flags); - blk_plug_device(q); - spin_unlock_irqrestore(q->queue_lock, flags); - + if (ide_cd_breathe(drive, rq)) return 1; - } } + do_end_request = 1; } else if (sense_key == UNIT_ATTENTION) { /* media change */ cdrom_saw_media_change(drive); -- cgit v1.2.2 From dfa4411cc3a690011cab90e9a536938795366cf9 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 8 Apr 2009 14:12:53 +0200 Subject: ide-cd: respect REQ_QUIET for fs requests in cdrom_decode_status() There should be no functional change resulting from this patch. Suggested-by: Bartlomiej Zolnierkiewicz Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 7bbdeb7e3bc4..c84abd6f9f6f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -312,6 +312,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; int err, sense_key; + u8 quiet = rq->cmd_flags & REQ_QUIET; /* get the IDE error register */ err = ide_read_error(drive); @@ -354,7 +355,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * drive doesn't have that capability. * cdrom_log_sense() knows this! */ - } else if (!(rq->cmd_flags & REQ_QUIET)) { + } else if (!quiet) { /* otherwise, print an error */ ide_dump_status(drive, "packet command error", stat); } @@ -382,7 +383,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) cdrom_saw_media_change(drive); /* fail the request */ - printk(KERN_ERR PFX "%s: tray open\n", + if (!quiet) + printk(KERN_ERR PFX "%s: tray open\n", drive->name); } else { if (ide_cd_breathe(drive, rq)) @@ -405,19 +407,23 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * No point in retrying after an illegal request or data * protect error. */ - ide_dump_status(drive, "command error", stat); + if (!quiet) + ide_dump_status(drive, "command error", stat); do_end_request = 1; } else if (sense_key == MEDIUM_ERROR) { /* * No point in re-trying a zillion times on a bad * sector. If we got here the error is not correctable. */ - ide_dump_status(drive, "media error (bad sector)", - stat); + if (!quiet) + ide_dump_status(drive, "media error " + "(bad sector)", stat); do_end_request = 1; } else if (sense_key == BLANK_CHECK) { /* disk appears blank ?? */ - ide_dump_status(drive, "media error (blank)", stat); + if (!quiet) + ide_dump_status(drive, "media error (blank)", + stat); do_end_request = 1; } else if ((err & ~ATA_ABORTED) != 0) { /* go to the default handler for other errors */ -- cgit v1.2.2 From 98036abf31994244cb5772ecc291f4293a52c20b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 8 Apr 2009 14:12:53 +0200 Subject: ide-cd: update debugging support Signed-off-by: Borislav Petkov [bart: extracted from "ide-cd: cleanup cdrom_decode_status" patch] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index c84abd6f9f6f..e946f0ecbb9c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -318,8 +318,9 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) err = ide_read_error(drive); sense_key = err >> 4; - ide_debug_log(IDE_DBG_RQ, "cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x", - rq->cmd[0], rq->cmd_type, err); + ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " + "stat 0x%x", + rq->cmd[0], rq->cmd_type, err, stat); if (blk_sense_request(rq)) { /* @@ -637,8 +638,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) u16 len; u8 ireason, stat; - ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", - rq->cmd[0], write); + ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write); /* check for errors */ dma = drive->dma; -- cgit v1.2.2 From e01f251fd09fa7cb3d352eac7de17bb5d5bd1f9d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 8 Apr 2009 14:12:53 +0200 Subject: ide-cd: convert cdrom_decode_status() to use switch statements Based on earlier work by Borislav Petkov. Convert cdrom_decode_status() to use switch statements in preparation to unify handling of fs and pc requests. While at it: - remove superfluous comments and do minor CodingStyle fixups There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 57 +++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index e946f0ecbb9c..43db330d7b5d 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -340,15 +340,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) if (blk_pc_request(rq) && !rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; - /* check for tray open */ - if (sense_key == NOT_READY) { + switch (sense_key) { + case NOT_READY: cdrom_saw_media_change(drive); - } else if (sense_key == UNIT_ATTENTION) { - /* check for media change */ + break; + case UNIT_ATTENTION: cdrom_saw_media_change(drive); return 0; - } else if (sense_key == ILLEGAL_REQUEST && - rq->cmd[0] == GPCMD_START_STOP_UNIT) { + case ILLEGAL_REQUEST: /* * Don't print error message for this condition-- * SFF8090i indicates that 5/24/00 is the correct @@ -356,9 +355,13 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * drive doesn't have that capability. * cdrom_log_sense() knows this! */ - } else if (!quiet) { - /* otherwise, print an error */ - ide_dump_status(drive, "packet command error", stat); + if (rq->cmd[0] == GPCMD_START_STOP_UNIT) + break; + /* fall-through */ + default: + if (!quiet) + ide_dump_status(drive, "packet command error", + stat); } rq->cmd_flags |= REQ_FAILED; @@ -378,12 +381,11 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) if (blk_noretry_request(rq)) do_end_request = 1; - if (sense_key == NOT_READY) { - /* tray open */ + switch (sense_key) { + case NOT_READY: if (rq_data_dir(rq) == READ) { cdrom_saw_media_change(drive); - /* fail the request */ if (!quiet) printk(KERN_ERR PFX "%s: tray open\n", drive->name); @@ -392,8 +394,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) return 1; } do_end_request = 1; - } else if (sense_key == UNIT_ATTENTION) { - /* media change */ + break; + case UNIT_ATTENTION: cdrom_saw_media_change(drive); /* @@ -402,8 +404,9 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) */ if (++rq->errors > ERROR_MAX) do_end_request = 1; - } else if (sense_key == ILLEGAL_REQUEST || - sense_key == DATA_PROTECT) { + break; + case ILLEGAL_REQUEST: + case DATA_PROTECT: /* * No point in retrying after an illegal request or data * protect error. @@ -411,7 +414,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) if (!quiet) ide_dump_status(drive, "command error", stat); do_end_request = 1; - } else if (sense_key == MEDIUM_ERROR) { + break; + case MEDIUM_ERROR: /* * No point in re-trying a zillion times on a bad * sector. If we got here the error is not correctable. @@ -420,19 +424,22 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) ide_dump_status(drive, "media error " "(bad sector)", stat); do_end_request = 1; - } else if (sense_key == BLANK_CHECK) { + break; + case BLANK_CHECK: /* disk appears blank ?? */ if (!quiet) ide_dump_status(drive, "media error (blank)", stat); do_end_request = 1; - } else if ((err & ~ATA_ABORTED) != 0) { - /* go to the default handler for other errors */ - ide_error(drive, "cdrom_decode_status", stat); - return 1; - } else if ((++rq->errors > ERROR_MAX)) { - /* we've racked up too many retries, abort */ - do_end_request = 1; + break; + default: + if (err & ~ATA_ABORTED) { + /* go to the default handler for other errors */ + ide_error(drive, "cdrom_decode_status", stat); + return 1; + } else if (++rq->errors > ERROR_MAX) + /* we've racked up too many retries, abort */ + do_end_request = 1; } /* -- cgit v1.2.2 From 1920c48d796ce7240ba267cb0be85c51895258f8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 8 Apr 2009 14:12:54 +0200 Subject: ide-cd: unify handling of fs and pc requests in cdrom_decode_status() Based on earlier work by Borislav Petkov. Unify handling of fs and pc requests in cdrom_decode_status(). While at it: - remove unreachable code The only change in functionality is that for pc requests more detailed error message will be printed for following sense keys: * ILLEGAL_REQUEST * DATA_PROTECT * MEDIUM_ERROR * BLANK_CHECK Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 69 ++++++++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 43db330d7b5d..ffbaa6d578ff 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -330,8 +330,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) */ rq->cmd_flags |= REQ_FAILED; return 2; - } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { - /* All other functions, except for READ. */ + } else { + int do_end_request = 0; /* * if we have an error, pass back CHECK_CONDITION as the @@ -340,53 +340,16 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) if (blk_pc_request(rq) && !rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; - switch (sense_key) { - case NOT_READY: - cdrom_saw_media_change(drive); - break; - case UNIT_ATTENTION: - cdrom_saw_media_change(drive); - return 0; - case ILLEGAL_REQUEST: - /* - * Don't print error message for this condition-- - * SFF8090i indicates that 5/24/00 is the correct - * response to a request to close the tray if the - * drive doesn't have that capability. - * cdrom_log_sense() knows this! - */ - if (rq->cmd[0] == GPCMD_START_STOP_UNIT) - break; - /* fall-through */ - default: - if (!quiet) - ide_dump_status(drive, "packet command error", - stat); - } - - rq->cmd_flags |= REQ_FAILED; - - /* - * instead of playing games with moving completions around, - * remove failed request completely and end it when the - * request sense has completed - */ - goto end_request; - - } else if (blk_fs_request(rq)) { - int do_end_request = 0; - - /* handle errors from READ and WRITE requests */ - if (blk_noretry_request(rq)) do_end_request = 1; switch (sense_key) { case NOT_READY: - if (rq_data_dir(rq) == READ) { + if (blk_fs_request(rq) == 0 || + rq_data_dir(rq) == READ) { cdrom_saw_media_change(drive); - if (!quiet) + if (blk_fs_request(rq) && !quiet) printk(KERN_ERR PFX "%s: tray open\n", drive->name); } else { @@ -398,6 +361,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) case UNIT_ATTENTION: cdrom_saw_media_change(drive); + if (blk_fs_request(rq) == 0) + return 0; /* * Arrange to retry the request but be sure to give up * if we've retried too many times. @@ -406,6 +371,16 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) do_end_request = 1; break; case ILLEGAL_REQUEST: + /* + * Don't print error message for this condition-- + * SFF8090i indicates that 5/24/00 is the correct + * response to a request to close the tray if the + * drive doesn't have that capability. + * cdrom_log_sense() knows this! + */ + if (rq->cmd[0] == GPCMD_START_STOP_UNIT) + break; + /* fall-through */ case DATA_PROTECT: /* * No point in retrying after an illegal request or data @@ -433,6 +408,8 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) do_end_request = 1; break; default: + if (blk_fs_request(rq) == 0) + break; if (err & ~ATA_ABORTED) { /* go to the default handler for other errors */ ide_error(drive, "cdrom_decode_status", stat); @@ -442,6 +419,11 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) do_end_request = 1; } + if (blk_fs_request(rq) == 0) { + rq->cmd_flags |= REQ_FAILED; + do_end_request = 1; + } + /* * End a request through request sense analysis when we have * sense data. We need this in order to perform end of media @@ -457,9 +439,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) if (stat & ATA_ERR) cdrom_queue_request_sense(drive, NULL, NULL); return 1; - } else { - blk_dump_rq_flags(rq, PFX "bad rq"); - return 2; } end_request: -- cgit v1.2.2 From 674f0ea111bc9bff1b4e4841d7da38933c5e3b59 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 8 Apr 2009 14:12:54 +0200 Subject: ide-cd: fix intendation in cdrom_decode_status() Based on earlier work by Borislav Petkov. Fix intendation in cdrom_decode_status(), no real code changes. While at it: - beautify comments There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 185 ++++++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 97 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ffbaa6d578ff..3ce1eafef5e4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -311,7 +311,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; - int err, sense_key; + int err, sense_key, do_end_request = 0; u8 quiet = rq->cmd_flags & REQ_QUIET; /* get the IDE error register */ @@ -330,117 +330,108 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) */ rq->cmd_flags |= REQ_FAILED; return 2; - } else { - int do_end_request = 0; - - /* - * if we have an error, pass back CHECK_CONDITION as the - * scsi status byte - */ - if (blk_pc_request(rq) && !rq->errors) - rq->errors = SAM_STAT_CHECK_CONDITION; + } - if (blk_noretry_request(rq)) - do_end_request = 1; + /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ + if (blk_pc_request(rq) && !rq->errors) + rq->errors = SAM_STAT_CHECK_CONDITION; - switch (sense_key) { - case NOT_READY: - if (blk_fs_request(rq) == 0 || - rq_data_dir(rq) == READ) { - cdrom_saw_media_change(drive); + if (blk_noretry_request(rq)) + do_end_request = 1; - if (blk_fs_request(rq) && !quiet) - printk(KERN_ERR PFX "%s: tray open\n", - drive->name); - } else { - if (ide_cd_breathe(drive, rq)) - return 1; - } - do_end_request = 1; - break; - case UNIT_ATTENTION: + switch (sense_key) { + case NOT_READY: + if (blk_fs_request(rq) == 0 || rq_data_dir(rq) == READ) { cdrom_saw_media_change(drive); - if (blk_fs_request(rq) == 0) - return 0; - /* - * Arrange to retry the request but be sure to give up - * if we've retried too many times. - */ - if (++rq->errors > ERROR_MAX) - do_end_request = 1; - break; - case ILLEGAL_REQUEST: - /* - * Don't print error message for this condition-- - * SFF8090i indicates that 5/24/00 is the correct - * response to a request to close the tray if the - * drive doesn't have that capability. - * cdrom_log_sense() knows this! - */ - if (rq->cmd[0] == GPCMD_START_STOP_UNIT) - break; - /* fall-through */ - case DATA_PROTECT: - /* - * No point in retrying after an illegal request or data - * protect error. - */ - if (!quiet) - ide_dump_status(drive, "command error", stat); - do_end_request = 1; - break; - case MEDIUM_ERROR: - /* - * No point in re-trying a zillion times on a bad - * sector. If we got here the error is not correctable. - */ - if (!quiet) - ide_dump_status(drive, "media error " - "(bad sector)", stat); - do_end_request = 1; - break; - case BLANK_CHECK: - /* disk appears blank ?? */ - if (!quiet) - ide_dump_status(drive, "media error (blank)", - stat); - do_end_request = 1; - break; - default: - if (blk_fs_request(rq) == 0) - break; - if (err & ~ATA_ABORTED) { - /* go to the default handler for other errors */ - ide_error(drive, "cdrom_decode_status", stat); + if (blk_fs_request(rq) && !quiet) + printk(KERN_ERR PFX "%s: tray open\n", + drive->name); + } else { + if (ide_cd_breathe(drive, rq)) return 1; - } else if (++rq->errors > ERROR_MAX) - /* we've racked up too many retries, abort */ - do_end_request = 1; } + do_end_request = 1; + break; + case UNIT_ATTENTION: + cdrom_saw_media_change(drive); - if (blk_fs_request(rq) == 0) { - rq->cmd_flags |= REQ_FAILED; - do_end_request = 1; - } + if (blk_fs_request(rq) == 0) + return 0; /* - * End a request through request sense analysis when we have - * sense data. We need this in order to perform end of media - * processing. + * Arrange to retry the request but be sure to give up if we've + * retried too many times. */ - if (do_end_request) - goto end_request; - + if (++rq->errors > ERROR_MAX) + do_end_request = 1; + break; + case ILLEGAL_REQUEST: + /* + * Don't print error message for this condition -- SFF8090i + * indicates that 5/24/00 is the correct response to a request + * to close the tray if the drive doesn't have that capability. + * + * cdrom_log_sense() knows this! + */ + if (rq->cmd[0] == GPCMD_START_STOP_UNIT) + break; + /* fall-through */ + case DATA_PROTECT: /* - * If we got a CHECK_CONDITION status, queue - * a request sense command. + * No point in retrying after an illegal request or data + * protect error. */ - if (stat & ATA_ERR) - cdrom_queue_request_sense(drive, NULL, NULL); - return 1; + if (!quiet) + ide_dump_status(drive, "command error", stat); + do_end_request = 1; + break; + case MEDIUM_ERROR: + /* + * No point in re-trying a zillion times on a bad sector. + * If we got here the error is not correctable. + */ + if (!quiet) + ide_dump_status(drive, "media error " + "(bad sector)", stat); + do_end_request = 1; + break; + case BLANK_CHECK: + /* disk appears blank? */ + if (!quiet) + ide_dump_status(drive, "media error (blank)", + stat); + do_end_request = 1; + break; + default: + if (blk_fs_request(rq) == 0) + break; + if (err & ~ATA_ABORTED) { + /* go to the default handler for other errors */ + ide_error(drive, "cdrom_decode_status", stat); + return 1; + } else if (++rq->errors > ERROR_MAX) + /* we've racked up too many retries, abort */ + do_end_request = 1; } + if (blk_fs_request(rq) == 0) { + rq->cmd_flags |= REQ_FAILED; + do_end_request = 1; + } + + /* + * End a request through request sense analysis when we have sense data. + * We need this in order to perform end of media processing. + */ + if (do_end_request) + goto end_request; + + /* if we got a CHECK_CONDITION status, queue a request sense command */ + if (stat & ATA_ERR) + cdrom_queue_request_sense(drive, NULL, NULL); + return 1; + end_request: if (stat & ATA_ERR) { struct request_queue *q = drive->queue; -- cgit v1.2.2 From 3c8a48e9a94be1e063f2f8d7d5f6f691423a3e71 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 8 Apr 2009 14:13:03 +0200 Subject: ide-cd: reverse NOT_READY sense key logic Make the case of flushing the drive's cache explicit. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3ce1eafef5e4..3aec19d1fdfc 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -341,15 +341,15 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) switch (sense_key) { case NOT_READY: - if (blk_fs_request(rq) == 0 || rq_data_dir(rq) == READ) { + if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { + if (ide_cd_breathe(drive, rq)) + return 1; + } else { cdrom_saw_media_change(drive); if (blk_fs_request(rq) && !quiet) printk(KERN_ERR PFX "%s: tray open\n", drive->name); - } else { - if (ide_cd_breathe(drive, rq)) - return 1; } do_end_request = 1; break; -- cgit v1.2.2 From a1f9a89c90b4ac143c5b6054c2a157572b272cd2 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 22 Apr 2009 20:33:40 +0200 Subject: ide-cd: fix kernel crash on hppa regression With 2.6.30-rc2 I face a kernel crash on the 32bit hppa architecture due to ide-cd when udev creates the device nodes at startup: Kernel Fault: Code=26 regs=8ed34c40 (Addr=00000024) IASQ: 00000000 00000000 IAOQ: 1034b5ac 1034b5b0 IIR: 4ab30048 ISR: 00000000 IOR: 00000024 CPU: 0 CR30: 8ed34000 CR31: ffff55ff ORIG_R28: 00000000 IAOQ[0]: ide_complete_rq+0x2c/0x70 IAOQ[1]: ide_complete_rq+0x30/0x70 RP(r2): cdrom_newpc_intr+0x178/0x46c Backtrace: [<1035c608>] cdrom_newpc_intr+0x178/0x46c [<1034c494>] ide_intr+0x1b0/0x214 [<1016d284>] handle_IRQ_event+0x70/0x150 [<1016d4b0>] __do_IRQ+0x14c/0x1cc [<102f7864>] superio_interrupt+0x88/0xbc [<1016d284>] handle_IRQ_event+0x70/0x150 [<1016d4b0>] __do_IRQ+0x14c/0x1cc [<10112efc>] do_cpu_irq_mask+0x9c/0xd0 [<10116068>] intr_return+0x0/0x4 This crash seems to happen due to an uninitialized variable "rc". The compiler even warns about that: CC drivers/ide/ide-cd.o /mnt/sda4/home/cvs/parisc/git-kernel/linus-linux-2.6/drivers/ide/ide-cd.c: In function `cdrom_newpc_intr': /mnt/sda4/home/cvs/parisc/git-kernel/linus-linux-2.6/drivers/ide/ide-cd.c:612: warning: `rc' might be used uninitialized in this function After applying the trivial patch below, which just initializes the variable to zero, the kernel doesn't crash any longer: Starting the hotplug events dispatcher: udevd. Synthesizing the initial hotplug events... hda: command error: status=0x51 { DriveReady SeekComplete Error } hda: command error: error=0x54 <3>{ AbortedCommand LastFailedSense=0x05 } ide: failed opcode was: unknown done. Signed-off-by: Helge Deller Acked-by: Borislav Petkov Cc: Linus Cc: Kyle McMartin Cc: "Rafael J. Wysocki" Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3aec19d1fdfc..3d4e09969763 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -609,7 +609,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) struct request *rq = hwif->rq; ide_expiry_t *expiry = NULL; int dma_error = 0, dma, thislen, uptodate = 0; - int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; + int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors; int sense = blk_sense_request(rq); unsigned int timeout; u16 len; -- cgit v1.2.2 From 96c16743973e8c1a7b9c655d10b7973408d6d1dd Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 30 Apr 2009 18:24:34 +0200 Subject: ide-cd: fix REQ_QUIET tests in cdrom_decode_status Original patch (dfa4411cc3a690011cab90e9a536938795366cf9) was buggy. This is a more proper fix which introduces blk_rq_quiet() macro alleviating the need for dumb, too short caching variables. Thanks to Helge Deller and Bart for debugging this. Signed-off-by: Borislav Petkov Cc: Jens Axboe Cc: Sergei Shtylyov Reported-and-tested-by: Helge Deller Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/ide/ide-cd.c') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3d4e09969763..925eb9e245d1 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -312,7 +312,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; int err, sense_key, do_end_request = 0; - u8 quiet = rq->cmd_flags & REQ_QUIET; /* get the IDE error register */ err = ide_read_error(drive); @@ -347,7 +346,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) } else { cdrom_saw_media_change(drive); - if (blk_fs_request(rq) && !quiet) + if (blk_fs_request(rq) && !blk_rq_quiet(rq)) printk(KERN_ERR PFX "%s: tray open\n", drive->name); } @@ -382,7 +381,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * No point in retrying after an illegal request or data * protect error. */ - if (!quiet) + if (!blk_rq_quiet(rq)) ide_dump_status(drive, "command error", stat); do_end_request = 1; break; @@ -391,14 +390,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * No point in re-trying a zillion times on a bad sector. * If we got here the error is not correctable. */ - if (!quiet) + if (!blk_rq_quiet(rq)) ide_dump_status(drive, "media error " "(bad sector)", stat); do_end_request = 1; break; case BLANK_CHECK: /* disk appears blank? */ - if (!quiet) + if (!blk_rq_quiet(rq)) ide_dump_status(drive, "media error (blank)", stat); do_end_request = 1; -- cgit v1.2.2