⬢ DragonFlyBSD Kernel Audit
DF-4355 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/sn/if_sn.c
+++ b/sys/dev/netif/sn/if_sn.c
@@ -272,8 +272,17 @@ sninit(void *xsc)
 	 */
 	SMC_SELECT_BANK(2);
 	outw(BASE + MMU_CMD_REG_W, MMUCR_RESET);
-	while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY)	/* NOTHING */
-		;
+	{
+		int _t = MEMORY_WAIT_TIME * 1000;
+		while ((inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) && --_t)
+			DELAY(1);
+		if (_t == 0) {
+			device_printf(sc->dev, "%s: MMU reset busy timeout\n",
+			    __func__);
+			return;
+		}
+	}
@@ -637,9 +646,18 @@ snresume(struct ifnet *ifp)
 		 * If the allocation was the wrong size we simply release the
 		 * memory once it is granted. Wait for the MMU to be un-busy.
 		 */
-		while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY)	/* NOTHING */
-			;
-		outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
+		{
+			int _t = MEMORY_WAIT_TIME * 1000;
+			while ((inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) && --_t)
+				DELAY(1);
+			if (_t == 0) {
+				kprintf("%s: MMU busy timeout\n", ifp->if_xname);
+				ifq_prepend(&ifp->if_snd, top);
+				return;
+			}
+			outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
+		}
@@ -867,9 +885,18 @@ sn_intr(void *arg)
 		 * kill the failed packet. Wait for the MMU to be un-busy.
 		 */
 		SMC_SELECT_BANK(2);
-		while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY)	/* NOTHING */
-			;
-		outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
+		{
+			int _t = MEMORY_WAIT_TIME * 1000;
+			while ((inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) && --_t)
+				DELAY(1);
+			if (_t == 0) {
+				kprintf("sn%d: MMU busy timeout (TX)\n",
+				    device_get_unit(sc->dev));
+				goto out;
+			}
+			outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
+		}
@@ -1052,9 +1079,18 @@ snread(struct ifnet *ifp)
 	 * Error or good, tell the card to get rid of this packet Wait for
 	 * the MMU to be un-busy.
 	 */
 	SMC_SELECT_BANK(2);
-	while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY)	/* NOTHING */
-		;
-	outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE);
+	{
+		int _t = MEMORY_WAIT_TIME * 1000;
+		while ((inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) && --_t)
+			DELAY(1);
+		if (_t == 0) {
+			kprintf("%s: MMU busy timeout (RX)\n", ifp->if_xname);
+			return;
+		}
+		outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE);
+	}