Re: [PATCH] try #2 even bigger natsemi patch

Manfred Spraul (manfred@colorfullife.com)
Sat, 20 Oct 2001 15:17:58 +0200


Tim Hockin wrote:
>
> static void netdev_timer(unsigned long data)
> {
> struct net_device *dev = (struct net_device *)data;
> struct netdev_private *np = dev->priv;
> - int next_tick = 60*HZ;
> + int next_tick = 5*HZ;
> + long ioaddr = dev->base_addr;
> + u16 dspcfg;
>
> if (debug > 3) {
> /* DO NOT read the IntrStatus register,
> @@ -933,10 +1107,27 @@
> dev->name);
> }
> spin_lock_irq(&np->lock);
> - check_link(dev);
> +
> + /* check for a nasty random phy-reset - use dspcfg as a flag */
> + writew(1, ioaddr+PGSEL);
> + dspcfg = readw(ioaddr+DSPCFG);
> + writew(0, ioaddr+PGSEL);
> + if (dspcfg != DSPCFG_VAL) {
> + if (!netif_queue_stopped(dev)) {
> + printk(KERN_INFO
> + "%s: possible phy reset: re-initializing\n",
> + dev->name);
> + init_registers(dev);
That's not SMP safe:
The interrupt handler acquires np->lock only for packet tx and errors,
not for packet rx.
Thus an rx interrupt could be running during init_registers - and
init_registers modifies the rx ring.
I think you must first check for the phy reset, and if you find a reset
then lock rx interrupts out with disable_irq.

disable_irq(dev->irq);
spin_lock_irq(&np->lock);

Calling disable_irq() always is probably too slow.

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