[PATCH] IDE configurable max failures

From: Tim Hockin (thockin@sun.com)
Date: Tue Jul 10 2001 - 02:04:11 EST


Andre et al,

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

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

Thanks

Tim

-- 
Tim Hockin
Systems Software Engineer
Sun Microsystems, Cobalt Server Appliances
thockin@sun.com

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

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jul 15 2001 - 21:00:11 EST