2001-07-10 06:57:11

by Tim Hockin

[permalink] [raw]
Subject: [PATCH] IDE configurable max failures

diff -ruN dist-2.4.6/drivers/ide/ide.c cobalt-2.4.6/drivers/ide/ide.c
--- dist-2.4.6/drivers/ide/ide.c Tue May 1 16:05:00 2001
+++ cobalt-2.4.6/drivers/ide/ide.c Thu Jun 21 15:32:31 2001
@@ -161,6 +162,9 @@
#include <linux/kmod.h>
#endif /* CONFIG_KMOD */

+/* default maximum number of failures */
+#define IDE_DEFAULT_MAX_FAILURES 1
+
static const byte ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR };

static int idebus_parameter; /* holds the "idebus=" parameter */
@@ -262,6 +267,7 @@
drive->name[0] = 'h';
drive->name[1] = 'd';
drive->name[2] = 'a' + (index * MAX_DRIVES) + unit;
+ drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
init_waitqueue_head(&drive->wqueue);
}
}
@@ -636,11 +642,14 @@
return ide_started; /* continue polling */
}
printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
+ drive->failures++;
} else {
printk("%s: reset: ", hwif->name);
- if ((tmp = GET_ERR()) == 1)
+ if ((tmp = GET_ERR()) == 1) {
printk("success\n");
- else {
+ drive->failures = 0;
+ } else {
+ drive->failures++;
#if FANCY_STATUS_DUMPS
printk("master: ");
switch (tmp & 0x7f) {
@@ -1048,6 +1057,12 @@
int i;
unsigned long flags;

+ /* bail early if we've exceeded max_failures */
+ if (drive->max_failures && (drive->failures > drive->max_failures)) {
+ *startstop = ide_stopped;
+ return 1;
+ }
+
udelay(1); /* spec allows drive 400ns to assert "BUSY" */
if ((stat = GET_STAT()) & BUSY_STAT) {
__save_flags(flags); /* local CPU only */
@@ -1144,6 +1159,11 @@
#ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
#endif
+ /* bail early if we've exceeded max_failures */
+ if (drive->max_failures && (drive->failures > drive->max_failures)) {
+ goto kill_rq;
+ }
+
if (unit >= MAX_DRIVES) {
printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev));
goto kill_rq;
diff -ruN dist-2.4.6/drivers/ide/ide-disk.c cobalt-2.4.6/drivers/ide/ide-disk.c
--- dist-2.4.6/drivers/ide/ide-disk.c Fri Feb 9 11:30:23 2001
+++ cobalt-2.4.6/drivers/ide/ide-disk.c Tue Jun 26 14:29:44 2001
@@ -692,6 +692,8 @@
ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL);
ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL);
+ ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
+ ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
}

/*
diff -ruN dist-2.4.6/include/linux/ide.h cobalt-2.4.6/include/linux/ide.h
--- dist-2.4.6/include/linux/ide.h Tue Jul 3 15:44:16 2001
+++ cobalt-2.4.6/include/linux/ide.h Mon Jul 9 15:56:19 2001
@@ -349,6 +350,8 @@
byte init_speed; /* transfer rate set at boot */
byte current_speed; /* current transfer rate set */
byte dn; /* now wide spread use */
+ unsigned int failures; /* current failure count */
+ unsigned int max_failures; /* maximum allowed failure count */
} ide_drive_t;

/*


Attachments:
ide_failures.diff (3.34 kB)

2001-07-10 09:46:29

by Alan Cox

[permalink] [raw]
Subject: Re: [PATCH] IDE configurable max failures

> Attached is a small patch to add a configurable maximum failure count for
> IDE drives. It has been very useful for us.

It doesnt do what you think or want I suspect

> Please let me know if there is any reason this can not be included in the
> mainline kernel.

Linus please dont apply this one. A correct ide retry patch is pending
merging from -ac. One that properly resets the ide state machines and
requeues the I/O