svn commit: r190030 - head/sys/dev/ichwd

Dag-Erling Smorgrav des at FreeBSD.org
Thu Mar 19 05:39:14 PDT 2009


Author: des
Date: Thu Mar 19 12:39:13 2009
New Revision: 190030
URL: http://svn.freebsd.org/changeset/base/190030

Log:
  Rename two functions to make their purpose clearer.  Add tons of comments.
  Generated code is identical after stripping .comment section.
  
  Suggested by:	Andriy Gapon <avg at icyb.net.ua>
  MFC after:	2 weeks

Modified:
  head/sys/dev/ichwd/ichwd.c

Modified: head/sys/dev/ichwd/ichwd.c
==============================================================================
--- head/sys/dev/ichwd/ichwd.c	Thu Mar 19 12:33:37 2009	(r190029)
+++ head/sys/dev/ichwd/ichwd.c	Thu Mar 19 12:39:13 2009	(r190030)
@@ -141,26 +141,55 @@ static devclass_t ichwd_devclass;
 			device_printf(dev, __VA_ARGS__);\
 	} while (0)
 
+/*
+ * Disable the watchdog timeout SMI handler.
+ *
+ * Apparently, some BIOSes install handlers that reset or disable the
+ * watchdog timer instead of resetting the system, so we disable the SMI
+ * (by clearing the SMI_TCO_EN bit of the SMI_EN register) to prevent this
+ * from happening.
+ */
 static __inline void
-ichwd_intr_enable(struct ichwd_softc *sc)
+ichwd_smi_disable(struct ichwd_softc *sc)
 {
 	ichwd_write_smi_4(sc, SMI_EN, ichwd_read_smi_4(sc, SMI_EN) & ~SMI_TCO_EN);
 }
 
+/*
+ * Enable the watchdog timeout SMI handler.  See above for details.
+ */
 static __inline void
-ichwd_intr_disable(struct ichwd_softc *sc)
+ichwd_smi_enable(struct ichwd_softc *sc)
 {
 	ichwd_write_smi_4(sc, SMI_EN, ichwd_read_smi_4(sc, SMI_EN) | SMI_TCO_EN);
 }
 
+/*
+ * Reset the watchdog status bits.
+ */
 static __inline void
 ichwd_sts_reset(struct ichwd_softc *sc)
 {
+	/*
+	 * The watchdog status bits are set to 1 by the hardware to
+	 * indicate various conditions.  They can be cleared by software
+	 * by writing a 1, not a 0.
+	 */
 	ichwd_write_tco_2(sc, TCO1_STS, TCO_TIMEOUT);
+	/*
+	 * XXX The datasheet says that TCO_SECOND_TO_STS must be cleared
+	 * before TCO_BOOT_STS, not the other way around.
+	 */
 	ichwd_write_tco_2(sc, TCO2_STS, TCO_BOOT_STS);
 	ichwd_write_tco_2(sc, TCO2_STS, TCO_SECOND_TO_STS);
 }
 
+/*
+ * Enable the watchdog timer by clearing the TCO_TMR_HALT bit in the
+ * TCO1_CNT register.  This is complicated by the need to preserve bit 9
+ * of that same register, and the requirement that all other bits must be
+ * written back as zero.
+ */
 static __inline void
 ichwd_tmr_enable(struct ichwd_softc *sc)
 {
@@ -172,6 +201,9 @@ ichwd_tmr_enable(struct ichwd_softc *sc)
 	ichwd_verbose_printf(sc->device, "timer enabled\n");
 }
 
+/*
+ * Disable the watchdog timer.  See above for details.
+ */
 static __inline void
 ichwd_tmr_disable(struct ichwd_softc *sc)
 {
@@ -183,6 +215,11 @@ ichwd_tmr_disable(struct ichwd_softc *sc
 	ichwd_verbose_printf(sc->device, "timer disabled\n");
 }
 
+/*
+ * Reload the watchdog timer: writing anything to any of the lower five
+ * bits of the TCO_RLD register reloads the timer from the last value
+ * written to TCO_TMR.
+ */
 static __inline void
 ichwd_tmr_reload(struct ichwd_softc *sc)
 {
@@ -194,6 +231,10 @@ ichwd_tmr_reload(struct ichwd_softc *sc)
 	ichwd_verbose_printf(sc->device, "timer reloaded\n");
 }
 
+/*
+ * Set the initial timeout value.  Note that this must always be followed
+ * by a reload.
+ */
 static __inline void
 ichwd_tmr_set(struct ichwd_softc *sc, unsigned int timeout)
 {
@@ -262,7 +303,8 @@ ichwd_clear_noreboot(struct ichwd_softc 
 }
 
 /*
- * Watchdog event handler.
+ * Watchdog event handler - called by the framework to enable or disable
+ * the watchdog or change the initial timeout value.
  */
 static void
 ichwd_event(void *arg, unsigned int cmd, int *error)
@@ -426,6 +468,13 @@ ichwd_attach(device_t dev)
 	device_printf(dev, "%s (ICH%d or equivalent)\n",
 	    device_get_desc(dev), sc->ich_version);
 
+	/*
+	 * XXX we should check the status registers (specifically, the
+	 * TCO_SECOND_TO_STS bit in the TCO2_STS register) to see if we
+	 * just came back from a watchdog-induced reset, and let the user
+	 * know.
+	 */
+
 	/* reset the watchdog status registers */
 	ichwd_sts_reset(sc);
 
@@ -435,8 +484,8 @@ ichwd_attach(device_t dev)
 	/* register the watchdog event handler */
 	sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, ichwd_event, sc, 0);
 
-	/* enable watchdog timeout interrupts */
-	ichwd_intr_enable(sc);
+	/* disable the SMI handler */
+	ichwd_smi_disable(sc);
 
 	return (0);
  fail:
@@ -466,8 +515,8 @@ ichwd_detach(device_t dev)
 	if (sc->active)
 		ichwd_tmr_disable(sc);
 
-	/* disable watchdog timeout interrupts */
-	ichwd_intr_disable(sc);
+	/* enable the SMI handler */
+	ichwd_smi_enable(sc);
 
 	/* deregister event handler */
 	if (sc->ev_tag != NULL)


More information about the svn-src-all mailing list