2002-12-29 01:04:57

by Paulo Andre'

[permalink] [raw]
Subject: [PATCH] 3c574_cs.c locking fixes

Hi,

This patch adds proper locking to the 3c574 pcmcia driver.

Paulo Andre'

---


--- 3c574_cs.c.orig 2002-12-28 23:55:58.000000000 +0000
+++ 3c574_cs.c 2002-12-29 01:00:44.000000000 +0000
@@ -221,6 +221,7 @@
u_short media_status;
u_short fast_poll;
u_long last_irq;
+ spinlock_t lock;
};

/* Set iff a MII transceiver on any interface requires mdio preamble.
@@ -1020,9 +1021,11 @@
{
struct el3_private *lp = (struct el3_private *)arg;
struct net_device *dev = &lp->dev;
+ unsigned long flags;
+
ioaddr_t ioaddr = dev->base_addr;
- u_long flags;
- u_short /* cable, */ media, partner;
+
+ u_short /* cable, */ media, partner;

if (!netif_device_present(dev))
goto reschedule;
@@ -1043,13 +1046,12 @@
return;
}

- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->lock, flags);
EL3WINDOW(4);
media = mdio_read(ioaddr, lp->phys, 1);
partner = mdio_read(ioaddr, lp->phys, 5);
EL3WINDOW(1);
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);

if (media != lp->media_status) {
if ((media ^ lp->media_status) & 0x0004)
@@ -1232,31 +1234,29 @@
case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
{
int saved_window;
- unsigned long flags;
+ unsigned long flags;

- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->lock, flags);
saved_window = inw(ioaddr + EL3_CMD) >> 13;
EL3WINDOW(4);
data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] &
0x1f); EL3WINDOW(saved_window);
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
return 0;
}
case SIOCDEVPRIVATE+2: /* Write the specified MII register */
{
int saved_window;
- unsigned long flags;
+ unsigned long flags;

if (!capable(CAP_NET_ADMIN))
return -EPERM;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&lp->lock, flags);
saved_window = inw(ioaddr + EL3_CMD) >> 13;
EL3WINDOW(4);
mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f,
data[2]); EL3WINDOW(saved_window);
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
return 0;
}
default: