From: Willem Riede - move ide_cdrom_dump_status() from ide-cd.c to ide-lib.c as ide_dump_atapi_status() and both ide-cd and ide-scsi call it. - replaces BUG() by WARN_ON()/printk in the error handling code. - sets TASK_UNINTERRUPTIBLE before schedule_timeout() and moves the host unlock/lock around the while loop inside the loop in idescsi_eh_reset(). --- drivers/ide/ide-cd.c | 51 +--------------------------------- drivers/ide/ide-lib.c | 52 +++++++++++++++++++++++++++++++++++ drivers/scsi/ide-scsi.c | 70 +++++++----------------------------------------- include/linux/ide.h | 1 4 files changed, 66 insertions(+), 108 deletions(-) diff -puN drivers/ide/ide-cd.c~ide-scsi-error-handling-update drivers/ide/ide-cd.c --- 25/drivers/ide/ide-cd.c~ide-scsi-error-handling-update 2004-03-07 17:26:00.000000000 -0800 +++ 25-akpm/drivers/ide/ide-cd.c 2004-03-07 17:26:00.000000000 -0800 @@ -554,53 +554,6 @@ static void cdrom_queue_request_sense(id (void) ide_do_drive_cmd(drive, rq, ide_preempt); } - -/* - * Error reporting, in human readable form (luxurious, but a memory hog). - */ -byte ide_cdrom_dump_status (ide_drive_t *drive, const char *msg, byte stat) -{ - unsigned long flags; - - atapi_status_t status; - atapi_error_t error; - - status.all = stat; - local_irq_set(flags); - printk("%s: %s: status=0x%02x", drive->name, msg, stat); -#if FANCY_STATUS_DUMPS - printk(" { "); - if (status.b.bsy) - printk("Busy "); - else { - if (status.b.drdy) printk("DriveReady "); - if (status.b.df) printk("DeviceFault "); - if (status.b.dsc) printk("SeekComplete "); - if (status.b.drq) printk("DataRequest "); - if (status.b.corr) printk("CorrectedError "); - if (status.b.idx) printk("Index "); - if (status.b.check) printk("Error "); - } - printk("}"); -#endif /* FANCY_STATUS_DUMPS */ - printk("\n"); - if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) { - error.all = HWIF(drive)->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x", drive->name, msg, error.all); -#if FANCY_STATUS_DUMPS - if (error.b.ili) printk("IllegalLengthIndication "); - if (error.b.eom) printk("EndOfMedia "); - if (error.b.abrt) printk("Aborted Command "); - if (error.b.mcr) printk("MediaChangeRequested "); - if (error.b.sense_key) printk("LastFailedSense 0x%02x ", - error.b.sense_key); -#endif /* FANCY_STATUS_DUMPS */ - printk("\n"); - } - local_irq_restore(flags); - return error.all; -} - /* * ide_error() takes action based on the error returned by the drive. */ @@ -609,7 +562,7 @@ ide_startstop_t ide_cdrom_error (ide_dri struct request *rq; byte err; - err = ide_cdrom_dump_status(drive, msg, stat); + err = ide_dump_atapi_status(drive, msg, stat); if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; /* retry only "normal" I/O: */ @@ -3411,7 +3364,7 @@ static ide_driver_t ide_cdrom_driver = { .supports_dsc_overlap = 1, .cleanup = ide_cdrom_cleanup, .do_request = ide_do_rw_cdrom, - .sense = ide_cdrom_dump_status, + .sense = ide_dump_atapi_status, .error = ide_cdrom_error, .abort = ide_cdrom_abort, .capacity = ide_cdrom_capacity, diff -puN drivers/ide/ide-lib.c~ide-scsi-error-handling-update drivers/ide/ide-lib.c --- 25/drivers/ide/ide-lib.c~ide-scsi-error-handling-update 2004-03-07 17:26:00.000000000 -0800 +++ 25-akpm/drivers/ide/ide-lib.c 2004-03-07 17:26:00.000000000 -0800 @@ -447,3 +447,55 @@ int ide_set_xfer_rate(ide_drive_t *drive EXPORT_SYMBOL_GPL(ide_set_xfer_rate); +/** + * ide_dump_atapi_status - print human readable atapi status + * @drive: drive that status applies to + * @msg: text message to print + * @stat: status byte to decode + * + * Error reporting, in human readable form (luxurious, but a memory hog). + */ +byte ide_dump_atapi_status (ide_drive_t *drive, const char *msg, byte stat) +{ + unsigned long flags; + + atapi_status_t status; + atapi_error_t error; + + status.all = stat; + local_irq_set(flags); + printk("%s: %s: status=0x%02x", drive->name, msg, stat); +#if FANCY_STATUS_DUMPS + printk(" { "); + if (status.b.bsy) + printk("Busy "); + else { + if (status.b.drdy) printk("DriveReady "); + if (status.b.df) printk("DeviceFault "); + if (status.b.dsc) printk("SeekComplete "); + if (status.b.drq) printk("DataRequest "); + if (status.b.corr) printk("CorrectedError "); + if (status.b.idx) printk("Index "); + if (status.b.check) printk("Error "); + } + printk("}"); +#endif /* FANCY_STATUS_DUMPS */ + printk("\n"); + if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) { + error.all = HWIF(drive)->INB(IDE_ERROR_REG); + printk("%s: %s: error=0x%02x", drive->name, msg, error.all); +#if FANCY_STATUS_DUMPS + if (error.b.ili) printk("IllegalLengthIndication "); + if (error.b.eom) printk("EndOfMedia "); + if (error.b.abrt) printk("Aborted Command "); + if (error.b.mcr) printk("MediaChangeRequested "); + if (error.b.sense_key) printk("LastFailedSense 0x%02x ", + error.b.sense_key); +#endif /* FANCY_STATUS_DUMPS */ + printk("\n"); + } + local_irq_restore(flags); + return error.all; +} + +EXPORT_SYMBOL(ide_dump_atapi_status); diff -puN drivers/scsi/ide-scsi.c~ide-scsi-error-handling-update drivers/scsi/ide-scsi.c --- 25/drivers/scsi/ide-scsi.c~ide-scsi-error-handling-update 2004-03-07 17:26:00.000000000 -0800 +++ 25-akpm/drivers/scsi/ide-scsi.c 2004-03-07 17:26:00.000000000 -0800 @@ -308,60 +308,12 @@ static int idescsi_check_condition(ide_d return ide_do_drive_cmd(drive, rq, ide_preempt); } -/* Code derived from ide_cdrom_error()/abort() -- see ide-cd.c */ - -/* - * Error reporting, in human readable form (luxurious, but a memory hog). - */ -byte idescsi_dump_status (ide_drive_t *drive, const char *msg, byte stat) -{ - unsigned long flags; - - atapi_status_t status; - atapi_error_t error; - - status.all = stat; - local_irq_set(flags); - printk(KERN_WARNING "ide-scsi: %s: %s: status=0x%02x", drive->name, msg, stat); -#if IDESCSI_DEBUG_LOG - printk(" { "); - if (status.b.bsy) - printk("Busy "); - else { - if (status.b.drdy) printk("DriveReady "); - if (status.b.df) printk("DeviceFault "); - if (status.b.dsc) printk("SeekComplete "); - if (status.b.drq) printk("DataRequest "); - if (status.b.corr) printk("CorrectedError "); - if (status.b.idx) printk("Index "); - if (status.b.check) printk("Error "); - } - printk("}"); -#endif /* IDESCSI_DEBUG_LOG */ - printk("\n"); - if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) { - error.all = HWIF(drive)->INB(IDE_ERROR_REG); - printk(KERN_WARNING "ide-scsi: %s: %s: error=0x%02x", drive->name, msg, error.all); -#if IDESCSI_DEBUG_LOG - if (error.b.ili) printk("IllegalLengthIndication "); - if (error.b.eom) printk("EndOfMedia "); - if (error.b.abrt) printk("Aborted Command "); - if (error.b.mcr) printk("MediaChangeRequested "); - if (error.b.sense_key) printk("LastFailedSense 0x%02x ", - error.b.sense_key); -#endif /* IDESCSI_DEBUG_LOG */ - printk("\n"); - } - local_irq_restore(flags); - return error.all; -} - ide_startstop_t idescsi_atapi_error (ide_drive_t *drive, const char *msg, byte stat) { struct request *rq; byte err; - err = idescsi_dump_status(drive, msg, stat); + err = ide_dump_atapi_status(drive, msg, stat); if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; @@ -980,7 +932,8 @@ static int idescsi_eh_abort (Scsi_Cmnd * printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number); if (!drive) { - BUG(); + printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n"); + WARN_ON(1); goto no_drive; } @@ -1039,14 +992,15 @@ static int idescsi_eh_reset (Scsi_Cmnd * printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number); if (!drive) { - BUG(); + printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n"); + WARN_ON(1); return FAILED; } spin_lock_irq(&ide_lock); if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { - BUG(); + printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); spin_unlock(&ide_lock); return FAILED; } @@ -1074,14 +1028,14 @@ static int idescsi_eh_reset (Scsi_Cmnd * ide_do_reset(drive); - spin_unlock_irq(cmd->device->host->host_lock); - /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */ - do - /* There should be no locks taken at this point */ + do { + set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock_irq(cmd->device->host->host_lock); schedule_timeout(HZ/20); - while ( HWGROUP(drive)->handler ); + spin_lock_irq(cmd->device->host->host_lock); + } while ( HWGROUP(drive)->handler ); ready = drive_is_ready(drive); HWGROUP(drive)->busy--; @@ -1090,8 +1044,6 @@ static int idescsi_eh_reset (Scsi_Cmnd * ret = FAILED; } - spin_lock_irq(cmd->device->host->host_lock); - return ret; } diff -puN include/linux/ide.h~ide-scsi-error-handling-update include/linux/ide.h --- 25/include/linux/ide.h~ide-scsi-error-handling-update 2004-03-07 17:26:00.000000000 -0800 +++ 25-akpm/include/linux/ide.h 2004-03-07 17:26:00.000000000 -0800 @@ -1643,6 +1643,7 @@ extern int ide_dma_enable(ide_drive_t *d extern char *ide_xfer_verbose(u8 xfer_rate); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); +extern byte ide_dump_atapi_status(ide_drive_t *drive, const char *msg, byte stat); typedef struct ide_pio_timings_s { int setup_time; /* Address setup (ns) minimum */ _