2009-04-30 09:49:40

by Wim Van Sebroeck

[permalink] [raw]
Subject: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Hi All,

I'm looking for people that can test the below patch(es).
I'm mainly interested in knowing if you experience any side-effects when using this patch.
(See also bugzilla 9868, 10195, 12363 & 12162).

For people not using the watchdog or without any reboot problems the driver should
work as normal after compilation/installation/...

For people that have the ICH9 reboot problems: load the module with module-parameter
gbl_smi_en=0 and test the watchdog functionality again.

Thanks in advance,
Wim.

The Changes are:

Author: Wim Van Sebroeck <[email protected]>
Date: Thu Apr 30 09:13:33 2009 +0000

[WATCHDOG] iTCO_wdt: Fix ICH9 reboot issue.

Bugzilla: 9868 & 10195.
There seems to be a bug into the SMM code that handles TCO Timeout SMI.
Andriy Gapon found that the code on his DG33TL system does the following:
> The handler is quite simple - it tests value in TCO1_CNT against 0x800, i.e.
> checks TCO_TMR_HLT. If the bit is set the handler goes into an infinite loop,
> apparently to allow the second timeout and reboot. Otherwise it simply clears
> TIMEOUT bit in TCO1_STS and that's it.
> So the logic seems to be reversed, because it is hard to see how TIMEOUT can
> get set to 1 and SMI generated when TCO_TMR_HLT is set (other than a
> transitional effect).

The only trick we have is to bypass the SMM code by turning of the generation
of the SMI#. The trick can only be enabled by setting the gbl_smi_en module
parameter to 0.

Signed-off-by: Wim Van Sebroeck <[email protected]>

Author: Wim Van Sebroeck <[email protected]>
Date: Tue Apr 14 20:20:07 2009 +0000

[WATCHDOG] iTCO_wdt: Cleanup code

Clean-up the iTCO_wdt code so that checkpatch.pl get's happy...

Signed-off-by: Wim Van Sebroeck <[email protected]>

The Changes can also be looked at on:
http://www.kernel.org/git/?p=linux/kernel/git/wim/linux-2.6-watchdog.git;a=summary

For completeness, I added the overal diff below.

Greetings,
Wim.

================================================================================
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index d3c0f6d..843ef62 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -35,9 +35,9 @@
#include "iTCO_vendor.h"

/* iTCO defines */
-#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
-#define TCOBASE acpibase + 0x60 /* TCO base address */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
+#define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */
+#define TCOBASE (acpibase + 0x60) /* TCO base address */
+#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */

/* List of vendor support modes */
/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 648250b..b76d1ec 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -63,7 +63,7 @@

/* Module and version information */
#define DRV_NAME "iTCO_wdt"
-#define DRV_VERSION "1.05"
+#define DRV_VERSION "1.06"
#define PFX DRV_NAME ": "

/* Includes */
@@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);

/* Address definitions for the TCO */
/* TCO base address */
-#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
+#define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60)
/* SMI Control and Enable Register */
-#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
-
-#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
-#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
-#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
-#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
-#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
-#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
-#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
-#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */
+#define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30)
+
+#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
+#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
+#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
+#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
+#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
+#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
+#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
+#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
+#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */

/* internal variables */
static unsigned long is_active;
@@ -277,6 +277,13 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
"(2<heartbeat<39 (TCO v1) or 613 (TCO v2), default="
__MODULE_STRING(WATCHDOG_HEARTBEAT) ")");

+#define GBL_SMI_EN_DEFAULT 1 /* 1 = don't turn GBL_SMI_EN off */
+static int gbl_smi_en = GBL_SMI_EN_DEFAULT;
+module_param(gbl_smi_en, int, 0);
+MODULE_PARM_DESC(gbl_smi_en,
+ "Turn GBL_SMI_EN off to fix reboot issues on ICH9..., default="
+ __MODULE_STRING(GBL_SMI_EN_DEFAULT) ")");
+
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout,
@@ -688,9 +695,12 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
ret = -EIO;
goto out;
}
- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
val32 = inl(SMI_EN);
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI#
+ Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH9. */
val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
+ if (gbl_smi_en == 0)
+ val32 &= 0xfffffffe; /* Turn off GBL_SMI_EN */
outl(val32, SMI_EN);

/* The TCO I/O registers reside in a 32-byte range pointed to
@@ -733,8 +743,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
goto unreg_region;
}

- printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
- heartbeat, nowayout);
+ printk(KERN_INFO PFX "initialized. heartbeat=%d sec, gbl_smi_en=%d "
+ "(nowayout=%d)\n", heartbeat, gbl_smi_en, nowayout);

return 0;


2009-04-30 10:44:52

by Andriy Gapon

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

on 30/04/2009 12:49 Wim Van Sebroeck said the following:
> Hi All,
>
> I'm looking for people that can test the below patch(es).
> I'm mainly interested in knowing if you experience any side-effects when using this patch.
> (See also bugzilla 9868, 10195, 12363 & 12162).
>
> For people not using the watchdog or without any reboot problems the driver should
> work as normal after compilation/installation/...
>
> For people that have the ICH9 reboot problems: load the module with module-parameter
> gbl_smi_en=0 and test the watchdog functionality again.

BTW: when I suggested a similar patch for FreeBSD ichwd driver I was advised to
prominently warn that globally disabling SMI could possibly lead to dramatic
problems, especially on laptops. I.e. various ACPI things where SMI is used for
communication between OS and firmware. I am not sure if this issue is applicable
to laptops at all, but just in case.

--
Andriy Gapon

2009-06-02 16:31:05

by Rui Santos

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Wim Van Sebroeck wrote:
> Hi All,
>
Hi Wim,
> I'm looking for people that can test the below patch(es).
> I'm mainly interested in knowing if you experience any side-effects when using this patch.
> (See also bugzilla 9868, 10195, 12363 & 12162).
>
> For people not using the watchdog or without any reboot problems the driver should
> work as normal after compilation/installation/...
>
> For people that have the ICH9 reboot problems: load the module with module-parameter
> gbl_smi_en=0 and test the watchdog functionality again.
>

Just to let you know that gbl_smi_en=0, also solves the problem with
Intel DG35EC motherboard, witch uses a 82801HB I/O Controller Hub (ICH8)

Regards,
Rui

> Thanks in advance,
> Wim.
>
> The Changes are:
>
> Author: Wim Van Sebroeck <[email protected]>
> Date: Thu Apr 30 09:13:33 2009 +0000
>
> [WATCHDOG] iTCO_wdt: Fix ICH9 reboot issue.
>
> Bugzilla: 9868 & 10195.
> There seems to be a bug into the SMM code that handles TCO Timeout SMI.
> Andriy Gapon found that the code on his DG33TL system does the following:
> > The handler is quite simple - it tests value in TCO1_CNT against 0x800, i.e.
> > checks TCO_TMR_HLT. If the bit is set the handler goes into an infinite loop,
> > apparently to allow the second timeout and reboot. Otherwise it simply clears
> > TIMEOUT bit in TCO1_STS and that's it.
> > So the logic seems to be reversed, because it is hard to see how TIMEOUT can
> > get set to 1 and SMI generated when TCO_TMR_HLT is set (other than a
> > transitional effect).
>
> The only trick we have is to bypass the SMM code by turning of the generation
> of the SMI#. The trick can only be enabled by setting the gbl_smi_en module
> parameter to 0.
>
> Signed-off-by: Wim Van Sebroeck <[email protected]>
>
> Author: Wim Van Sebroeck <[email protected]>
> Date: Tue Apr 14 20:20:07 2009 +0000
>
> [WATCHDOG] iTCO_wdt: Cleanup code
>
> Clean-up the iTCO_wdt code so that checkpatch.pl get's happy...
>
> Signed-off-by: Wim Van Sebroeck <[email protected]>
>
> The Changes can also be looked at on:
> http://www.kernel.org/git/?p=linux/kernel/git/wim/linux-2.6-watchdog.git;a=summary
>
> For completeness, I added the overal diff below.
>
> Greetings,
> Wim.
>
> ================================================================================
> diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
> index d3c0f6d..843ef62 100644
> --- a/drivers/watchdog/iTCO_vendor_support.c
> +++ b/drivers/watchdog/iTCO_vendor_support.c
> @@ -35,9 +35,9 @@
> #include "iTCO_vendor.h"
>
> /* iTCO defines */
> -#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
> -#define TCOBASE acpibase + 0x60 /* TCO base address */
> -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
> +#define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */
> +#define TCOBASE (acpibase + 0x60) /* TCO base address */
> +#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
>
> /* List of vendor support modes */
> /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
> diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
> index 648250b..b76d1ec 100644
> --- a/drivers/watchdog/iTCO_wdt.c
> +++ b/drivers/watchdog/iTCO_wdt.c
> @@ -63,7 +63,7 @@
>
> /* Module and version information */
> #define DRV_NAME "iTCO_wdt"
> -#define DRV_VERSION "1.05"
> +#define DRV_VERSION "1.06"
> #define PFX DRV_NAME ": "
>
> /* Includes */
> @@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
>
> /* Address definitions for the TCO */
> /* TCO base address */
> -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
> +#define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60)
> /* SMI Control and Enable Register */
> -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
> -
> -#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
> -#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
> -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
> -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
> -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
> -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
> -#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
> -#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
> -#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */
> +#define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30)
> +
> +#define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
> +#define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */
> +#define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */
> +#define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */
> +#define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */
> +#define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */
> +#define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */
> +#define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */
> +#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
>
> /* internal variables */
> static unsigned long is_active;
> @@ -277,6 +277,13 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
> "(2<heartbeat<39 (TCO v1) or 613 (TCO v2), default="
> __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
>
> +#define GBL_SMI_EN_DEFAULT 1 /* 1 = don't turn GBL_SMI_EN off */
> +static int gbl_smi_en = GBL_SMI_EN_DEFAULT;
> +module_param(gbl_smi_en, int, 0);
> +MODULE_PARM_DESC(gbl_smi_en,
> + "Turn GBL_SMI_EN off to fix reboot issues on ICH9..., default="
> + __MODULE_STRING(GBL_SMI_EN_DEFAULT) ")");
> +
> static int nowayout = WATCHDOG_NOWAYOUT;
> module_param(nowayout, int, 0);
> MODULE_PARM_DESC(nowayout,
> @@ -688,9 +695,12 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
> ret = -EIO;
> goto out;
> }
> - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
> val32 = inl(SMI_EN);
> + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI#
> + Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH9. */
> val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
> + if (gbl_smi_en == 0)
> + val32 &= 0xfffffffe; /* Turn off GBL_SMI_EN */
> outl(val32, SMI_EN);
>
> /* The TCO I/O registers reside in a 32-byte range pointed to
> @@ -733,8 +743,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
> goto unreg_region;
> }
>
> - printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
> - heartbeat, nowayout);
> + printk(KERN_INFO PFX "initialized. heartbeat=%d sec, gbl_smi_en=%d "
> + "(nowayout=%d)\n", heartbeat, gbl_smi_en, nowayout);
>
> return 0;
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>
>
>

2009-06-03 21:04:56

by Wim Van Sebroeck

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Hi Rui,

> Just to let you know that gbl_smi_en=0, also solves the problem with
> Intel DG35EC motherboard, witch uses a 82801HB I/O Controller Hub (ICH8)

Thanks for the feedback. I'm going to put the code in the iTCO_vendor_support code
so that the iTCO_wdt watchdog code stays clean. The glb_smi_en is and stays a dirty
hack... (and I will also document it as such). The real solution is to have the BIOS
code fixed...

Kind regards,
Wim.

2009-06-05 18:46:32

by Rui Santos

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Wim Van Sebroeck wrote:
> Hi All,
>
Hi Wim, Hi All,
> I'm looking for people that can test the below patch(es).
> I'm mainly interested in knowing if you experience any side-effects when using this patch.
> (See also bugzilla 9868, 10195, 12363 & 12162).
>
> For people not using the watchdog or without any reboot problems the driver should
> work as normal after compilation/installation/...
>
> For people that have the ICH9 reboot problems: load the module with module-parameter
> gbl_smi_en=0 and test the watchdog functionality again.
>

With your patch, the Intel DG35EC board will not allow my distribution
reboot or halt the machine. In order to circumvent that problem, I've
made a few addition to your previous patch witch allows the restore of
the changed Bit 0 to it's previous value if the module is unloaded.
My only doubt is if it should be done every time the gbl_smi_en is zero,
or in conjunction with nowayout when the value also equals zero. This
patch has what I described and a commented gbl_smi_en only.

Can anyone share his/her thoughts on this matter.

> Thanks in advance,
> Wim.
>
Regards,
Rui


Attachments:
linux-2.6.30-rc8-watchdog.patch (2.72 kB)

2009-06-10 08:19:04

by Wim Van Sebroeck

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Hi Rui,

> With your patch, the Intel DG35EC board will not allow my distribution
> reboot or halt the machine. In order to circumvent that problem, I've
> made a few addition to your previous patch witch allows the restore of
> the changed Bit 0 to it's previous value if the module is unloaded.
> My only doubt is if it should be done every time the gbl_smi_en is zero,
> or in conjunction with nowayout when the value also equals zero. This
> patch has what I described and a commented gbl_smi_en only.

Forget the previous patch. I don't like having this hack in the main iTCO_wdt code.
So I added it to the iTCO_vendor_support code with the necessary warnings.
Can you test this (please note that the iTCO_vendor_support module needs to be
loaded with the vendorsupport=911 module parameter).

Thanks in advance,
Wim.

---
commit 8a590d97277819e6693a47ca776ceee9ac74fda3
Author: Wim Van Sebroeck <[email protected]>
Date: Mon Jun 8 17:41:51 2009 +0000

[WATCHDOG] iTCO_wdt: Fix ICH7+ reboot issue.

Bugzilla: 9868 & 10195.
There seems to be a bug into the SMM code that handles TCO Timeout SMI.
Andriy Gapon found that the code on his DG33TL system does the following:
> The handler is quite simple - it tests value in TCO1_CNT against 0x800, i.e.
> checks TCO_TMR_HLT. If the bit is set the handler goes into an infinite loop,
> apparently to allow the second timeout and reboot. Otherwise it simply clears
> TIMEOUT bit in TCO1_STS and that's it.
> So the logic seems to be reversed, because it is hard to see how TIMEOUT can
> get set to 1 and SMI generated when TCO_TMR_HLT is set (other than a
> transitional effect).

The only trick we have is to bypass the SMM code by turning of the generation
of the SMI#. The trick can only be enabled by setting the vendorsupport module
parameter to 911. This trick doesn't work well on laptop's.

Note: this is a dirty hack. Please handle with care. The only real fix is that
the bug in the SMM bios code get's fixed.

Signed-off-by: Wim Van Sebroeck <[email protected]>

diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index 843ef62..5133bca 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -19,7 +19,7 @@

/* Module and version information */
#define DRV_NAME "iTCO_vendor_support"
-#define DRV_VERSION "1.03"
+#define DRV_VERSION "1.04"
#define PFX DRV_NAME ": "

/* Includes */
@@ -44,11 +44,14 @@
#define SUPERMICRO_OLD_BOARD 1
/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
#define SUPERMICRO_NEW_BOARD 2
+/* Broken BIOS */
+#define BROKEN_BIOS 911

static int vendorsupport;
module_param(vendorsupport, int, 0);
MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default="
- "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
+ "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+, "
+ "911=Broken SMI BIOS");

/*
* Vendor Specific Support
@@ -243,25 +246,92 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
}

/*
+ * Vendor Support: 911
+ * Board: Some Intel ICHx based motherboards
+ * iTCO chipset: ICH7+
+ *
+ * Some Intel motherboards have a broken BIOS implementation: i.e.
+ * the SMI handler clear's the TIMEOUT bit in the TC01_STS register
+ * and does not reload the time. Thus the TCO watchdog does not reboot
+ * the system.
+ *
+ * These are the conclusions of Andriy Gapon <[email protected]> after
+ * debugging: the SMI handler is quite simple - it tests value in
+ * TCO1_CNT against 0x800, i.e. checks TCO_TMR_HLT. If the bit is set
+ * the handler goes into an infinite loop, apparently to allow the
+ * second timeout and reboot. Otherwise it simply clears TIMEOUT bit
+ * in TCO1_STS and that's it.
+ * So the logic seems to be reversed, because it is hard to see how
+ * TIMEOUT can get set to 1 and SMI generated when TCO_TMR_HLT is set
+ * (other than a transitional effect).
+ *
+ * The only fix found to get the motherboard(s) to reboot is to put
+ * the glb_smi_en bit to 0. This is a dirty hack that bypasses the
+ * broken code by disabling Global SMI.
+ *
+ * WARNING: globally disabling SMI could possibly lead to dramatic
+ * problems, especially on laptops! I.e. various ACPI things where
+ * SMI is used for communication between OS and firmware.
+ *
+ * Don't use this fix if you don't need to!!!
+ */
+
+static void broken_bios_start(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ val32 = inl(SMI_EN);
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI#
+ Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */
+ val32 &= 0xffffdffe;
+ outl(val32, SMI_EN);
+}
+
+static void broken_bios_stop(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ val32 = inl(SMI_EN);
+ /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI#
+ Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */
+ val32 |= 0x00002001;
+ outl(val32, SMI_EN);
+}
+
+/*
* Generic Support Functions
*/

void iTCO_vendor_pre_start(unsigned long acpibase,
unsigned int heartbeat)
{
- if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ switch (vendorsupport) {
+ case SUPERMICRO_OLD_BOARD:
supermicro_old_pre_start(acpibase);
- else if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ break;
+ case SUPERMICRO_NEW_BOARD:
supermicro_new_pre_start(heartbeat);
+ break;
+ case BROKEN_BIOS:
+ broken_bios_start(acpibase);
+ break;
+ }
}
EXPORT_SYMBOL(iTCO_vendor_pre_start);

void iTCO_vendor_pre_stop(unsigned long acpibase)
{
- if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ switch (vendorsupport) {
+ case SUPERMICRO_OLD_BOARD:
supermicro_old_pre_stop(acpibase);
- else if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ break;
+ case SUPERMICRO_NEW_BOARD:
supermicro_new_pre_stop();
+ break;
+ case BROKEN_BIOS:
+ broken_bios_stop(acpibase);
+ break;
+ }
}
EXPORT_SYMBOL(iTCO_vendor_pre_stop);

2009-06-15 20:21:16

by Rui Santos

[permalink] [raw]
Subject: Re: [WATCHDOG] iTCO_wdt.c - ICH9 reboot issue - testing wanted

Wim Van Sebroeck wrote:
> Hi Rui,
>

Hi Wim,

>
>> With your patch, the Intel DG35EC board will not allow my distribution
>> reboot or halt the machine. In order to circumvent that problem, I've
>> made a few addition to your previous patch witch allows the restore of
>> the changed Bit 0 to it's previous value if the module is unloaded.
>> My only doubt is if it should be done every time the gbl_smi_en is zero,
>> or in conjunction with nowayout when the value also equals zero. This
>> patch has what I described and a commented gbl_smi_en only.
>>
>
> Forget the previous patch. I don't like having this hack in the main iTCO_wdt code.
> So I added it to the iTCO_vendor_support code with the necessary warnings.
> Can you test this (please note that the iTCO_vendor_support module needs to be
> loaded with the vendorsupport=911 module parameter).
>

It's working like a charm. Also, the Bit 0 is changed to its original
value, so all reboots work.
I've tested on 2.6.30 and 2.6.27 ( with a few mods... ).

> Thanks in advance,
>

Thank you,

> Wim.
>

Rui