DragonFlyBSD Kernel Audit
DF-2003 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/misc/ipmi/ipmi_smic.c b/sys/dev/misc/ipmi/ipmi_smic.c
--- a/sys/dev/misc/ipmi/ipmi_smic.c
+++ b/sys/dev/misc/ipmi/ipmi_smic.c
@@ -45,39 +45,57 @@
 #include <dev/misc/ipmi/ipmivars.h>
 #endif
 
-static void	smic_wait_for_tx_okay(struct ipmi_softc *);
-static void	smic_wait_for_rx_okay(struct ipmi_softc *);
-static void	smic_wait_for_not_busy(struct ipmi_softc *);
+static int	smic_wait_for_tx_okay(struct ipmi_softc *);
+static int	smic_wait_for_rx_okay(struct ipmi_softc *);
+static int	smic_wait_for_not_busy(struct ipmi_softc *);
 static void	smic_set_busy(struct ipmi_softc *);
 
-static void
+static int
 smic_wait_for_tx_okay(struct ipmi_softc *sc)
 {
 	int flags;
+	int start = ticks;
 
 	do {
 		flags = INB(sc, SMIC_FLAGS);
-	} while (!(flags & SMIC_STATUS_TX_RDY));
+		if (flags & SMIC_STATUS_TX_RDY)
+			return (1);
+		DELAY(100);
+	} while ((ticks - start) < MAX_TIMEOUT);
+	device_printf(sc->ipmi_dev, "SMIC: TX_RDY timeout\n");
+	return (0);
 }
 
-static void
+static int
 smic_wait_for_rx_okay(struct ipmi_softc *sc)
 {
 	int flags;
+	int start = ticks;
 
 	do {
 		flags = INB(sc, SMIC_FLAGS);
-	} while (!(flags & SMIC_STATUS_RX_RDY));
+		if (flags & SMIC_STATUS_RX_RDY)
+			return (1);
+		DELAY(100);
+	} while ((ticks - start) < MAX_TIMEOUT);
+	device_printf(sc->ipmi_dev, "SMIC: RX_RDY timeout\n");
+	return (0);
 }
 
-static void
+static int
 smic_wait_for_not_busy(struct ipmi_softc *sc)
 {
 	int flags;
+	int start = ticks;
 
 	do {
 		flags = INB(sc, SMIC_FLAGS);
-	} while (flags & SMIC_STATUS_BUSY);
+		if (!(flags & SMIC_STATUS_BUSY))
+			return (1);
+		DELAY(100);
+	} while ((ticks - start) < MAX_TIMEOUT);
+	device_printf(sc->ipmi_dev, "SMIC: not-busy timeout\n");
+	return (0);
 }
 
 static void