Re: 3com 3c905c-txm

From: Andrew Morton (andrewm@uow.edu.au)
Date: Wed May 10 2000 - 23:34:15 EST


Alan Cox wrote:
>
> > > 00:0e.0 Ethernet controller: 3Com Corporation: Unknown device 9004 (rev 04)
> >
> > Support for this NIC was introduced in 2.2.16pre2
>
> And will be going out in 2.2.16pre3 again I suspect. I've got a large
> collection of random box hang reports all of which go away if they use
> 3c59x.c from 2.2.15
>
> Any ideas ?

Repeat 100 times: "I will test patches on UP". It is an incomplete
merge of the interrupt deferral stuff - thanks Andreas. It can result
in the adding of a zero-duration timer in a BH handler. A fix is
attached. The relevant part is the initialisation of 'next_tick' in
vortex_timer().

I have snuck an additional patch into here, BTW. In several places the
driver
does this:

    outw(some_command, ioaddr + EL3_CMD);
    for (i = 2000; i >= 0 ; i--)
        if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
            break;

sometimes this timeout actually expires, which is why it was bumped to
4000 in 2.3. The docs are vague in this area. Bogdan has confirmed that
this fixes some crashes he has been experiencing. We end up talking to
the NIC before it is ready and, we believe, DMAing packets to/from
random bus addresses...

So in this patch I have simply increased the values to 4000. This is a
temp thing to keep people out of trouble. I suspect longer term we'll
be increasing the timeout to 1e6 and calling panic() if it expires.
We'll see.

There are a lot of these magical busywait timeout loops in the kernel.
Some attempt to scale their count by loops_per_sec, but the recent
bogomips changes have made this practice unreliable. Advancing
processor speeds continue to disrupt it.

I can't really think of a suitable alternative, apart from spinning on
the value of 'jiffies' or doing custom loop calibration. This is my
third gripe about this issue; ironic indeed that I am the first to be
bitten by it.

-- 
-akpm-

--- linux-2.2.16-pre2/drivers/net/3c59x.c.orig Thu May 11 13:20:05 2000 +++ linux-2.2.16-pre2/drivers/net/3c59x.c Thu May 11 14:22:14 2000 @@ -38,7 +38,7 @@ */ static char *version = -"3c59x.c:v0.99H 11/17/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; +"3c59x.c:v0.99H 12May00 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; /* "Knobs" that adjust features and parameters. */ /* Set the copy breakpoint for the copy-only-tiny-frames scheme. @@ -1096,13 +1096,13 @@ } outw(TxReset, ioaddr + EL3_CMD); - for (i = 2000; i >= 0 ; i--) + for (i = 4000; i >= 0 ; i--) if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) break; outw(RxReset, ioaddr + EL3_CMD); /* Wait a few ticks for the RxReset command to complete. */ - for (i = 2000; i >= 0 ; i--) + for (i = 4000; i >= 0 ; i--) if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) break; @@ -1224,7 +1224,7 @@ struct device *dev = (struct device *)data; struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; - int next_tick = 0; + int next_tick = 60 * HZ; int ok = 0; int media_status, mii_status, old_window; @@ -1467,7 +1467,7 @@ /* Adapter failure requires Tx/Rx reset and reinit. */ if (vp->full_bus_master_tx) { outw(TotalReset | 0xff, ioaddr + EL3_CMD); - for (i = 2000; i >= 0 ; i--) + for (i = 4000; i >= 0 ; i--) if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) break; /* Re-enable the receiver. */ @@ -1477,7 +1477,7 @@ do_tx_reset = 1; if (fifo_diag & 0x3000) { outw(RxReset, ioaddr + EL3_CMD); - for (i = 2000; i >= 0 ; i--) + for (i = 4000; i >= 0 ; i--) if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) break; /* Set the Rx filter to the current state. */

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:17 EST