SOLUTION? 2.2.x and DELL WS 400 or 200 (3c59x.c)

Richard Black rjb@dcs.gla.ac.uk
Wed Sep 1 11:13:33 1999


--==_Exmh_8127868000
Content-Type: text/plain; charset="us-ascii"


For some time I had been having problems with a DELL WS 400 crashing in the 
3c59x driver on 2.2.x kernel series, where it had been stable on 2.0.36.

My thanks to those who are receiving direct copies of this mail, who have 
either reported having the same problem or who have made helpful suggestions.
I am also copying this to the linux kernel development list and the vortex bug 
list.

I made an alteration myself to the 3c59x.c driver a week ago and have not had 
any crashes since.  Of course this could just be luck, but I think not. I 
enclose the patch which makes (for me) the 3c59x.c driver not crash. It seems 
that the driver's invariants are broken if the live-lock trigger to stop 
handling interrupts is ever executed.

Alan, I strongly recommend doing this in the current kernel release source.
These patches are for the version:

"3c59x.c:v0.99L 5/28/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers
/vortex.html"

Richard.



--==_Exmh_8127868000
Content-Description: a
Content-Disposition: attachment; filename="a"
Content-Type: text/plain; name="a"; charset="us-ascii"

--- 3c59x.c	1999/08/25 19:38:21	1.2
+++ 3c59x.c	1999/08/26 09:00:11	1.4
@@ -117,9 +117,9 @@
 #define PCI_SUPPORT_VER2
 #endif
 #if LINUX_VERSION_CODE < 0x20159
-#define DEV_FREE_SKB(skb) dev_kfree_skb (skb, FREE_WRITE);
+#define DEV_FREE_SKB(skb) dev_kfree_skb (skb, FREE_WRITE)
 #else  /* Grrr, incompatible changes should change the name. */
-#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
+#define DEV_FREE_SKB(skb) dev_kfree_skb(skb)
 #endif
 #if ! defined(CAP_NET_ADMIN)
 #define capable(CAP_XXX) (suser())
@@ -1656,7 +1656,11 @@
 		if (status & DMADone) {
 			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
 				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
+				if (vp->tx_skb) {
+					DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
+					vp->tx_skb = NULL;
+				} else
+					printk(KERN_WARNING "vortex would have crashed here (RJB)\n");
 				if (inw(ioaddr + TxFree) > 1536) {
 					clear_bit(0, (void*)&dev->tbusy);
 					mark_bh(NET_BH);
@@ -1670,7 +1674,7 @@
 				break;
 			vortex_error(dev, status);
 		}
-
+#if 0
 		if (--work_done < 0) {
 			if ((status & (0x7fe - (UpComplete | DownComplete))) == 0) {
 				/* Just ack these and return. */
@@ -1686,6 +1690,12 @@
 				break;
 			}
 		}
+#else
+		if (--work_done < 0)
+			if (((status & (0x7fe - (UpComplete | DownComplete))) != 0))
+				printk(KERN_WARNING "vortex would have locked up here (RJB)\n");
+#endif
+
 		/* Acknowledge the IRQ. */
 		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
 		if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */

--==_Exmh_8127868000--