
From: Willem Riede <wrlk@riede.org>

- 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 */

_
