Commit 93751bd2 authored by Jeff Garzik's avatar Jeff Garzik

[netdrvr 8139cp] locking cleanups

* s/spin_lock_irq/spin_lock_irqsave/ where it was simple and
  easy to verify.
* release spinlock earlier in interrupt routine.
parent 96f93003
...@@ -426,24 +426,26 @@ static struct { ...@@ -426,24 +426,26 @@ static struct {
static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp->vlgrp = grp; cp->vlgrp = grp;
cp->cpcmd |= RxVlanOn; cp->cpcmd |= RxVlanOn;
cpw16(CpCmd, cp->cpcmd); cpw16(CpCmd, cp->cpcmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd &= ~RxVlanOn; cp->cpcmd &= ~RxVlanOn;
cpw16(CpCmd, cp->cpcmd); cpw16(CpCmd, cp->cpcmd);
if (cp->vlgrp) if (cp->vlgrp)
cp->vlgrp->vlan_devices[vid] = NULL; cp->vlgrp->vlan_devices[vid] = NULL;
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
#endif /* CP_VLAN_TAG_USED */ #endif /* CP_VLAN_TAG_USED */
...@@ -649,20 +651,23 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -649,20 +651,23 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
/* close possible race's with dev_close */ /* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) { if (unlikely(!netif_running(dev))) {
cpw16(IntrMask, 0); cpw16(IntrMask, 0);
goto out; spin_unlock(&cp->lock);
return IRQ_HANDLED;
} }
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) { if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
if (netif_rx_schedule_prep(dev)) { if (netif_rx_schedule_prep(dev)) {
cpw16_f(IntrMask, cp_norx_intr_mask); cpw16_f(IntrMask, cp_norx_intr_mask);
__netif_rx_schedule(dev); __netif_rx_schedule(dev);
} }
}
if (status & (TxOK | TxErr | TxEmpty | SWInt)) if (status & (TxOK | TxErr | TxEmpty | SWInt))
cp_tx(cp); cp_tx(cp);
if (status & LinkChg) if (status & LinkChg)
mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);
spin_unlock(&cp->lock);
if (status & PciErr) { if (status & PciErr) {
u16 pci_status; u16 pci_status;
...@@ -673,8 +678,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -673,8 +678,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
/* TODO: reset hardware */ /* TODO: reset hardware */
} }
out:
spin_unlock(&cp->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -957,12 +961,13 @@ static void __cp_get_stats(struct cp_private *cp) ...@@ -957,12 +961,13 @@ static void __cp_get_stats(struct cp_private *cp)
static struct net_device_stats *cp_get_stats(struct net_device *dev) static struct net_device_stats *cp_get_stats(struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
/* The chip only need report frame silently dropped. */ /* The chip only need report frame silently dropped. */
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
if (netif_running(dev) && netif_device_present(dev)) if (netif_running(dev) && netif_device_present(dev))
__cp_get_stats(cp); __cp_get_stats(cp);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return &cp->net_stats; return &cp->net_stats;
} }
...@@ -1186,6 +1191,7 @@ static int cp_open (struct net_device *dev) ...@@ -1186,6 +1191,7 @@ static int cp_open (struct net_device *dev)
static int cp_close (struct net_device *dev) static int cp_close (struct net_device *dev)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
if (netif_msg_ifdown(cp)) if (netif_msg_ifdown(cp))
printk(KERN_DEBUG "%s: disabling interface\n", dev->name); printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
...@@ -1193,9 +1199,9 @@ static int cp_close (struct net_device *dev) ...@@ -1193,9 +1199,9 @@ static int cp_close (struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
netif_carrier_off(dev); netif_carrier_off(dev);
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp_stop_hw(cp); cp_stop_hw(cp);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
cp_free_rings(cp); cp_free_rings(cp);
...@@ -1207,6 +1213,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1207,6 +1213,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
int rc; int rc;
unsigned long flags;
/* check for invalid MTU, according to hardware limits */ /* check for invalid MTU, according to hardware limits */
if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU) if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU)
...@@ -1219,7 +1226,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1219,7 +1226,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
cp_stop_hw(cp); /* stop h/w and free rings */ cp_stop_hw(cp); /* stop h/w and free rings */
cp_clean_rings(cp); cp_clean_rings(cp);
...@@ -1230,7 +1237,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1230,7 +1237,7 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
rc = cp_init_rings(cp); /* realloc and restart h/w */ rc = cp_init_rings(cp); /* realloc and restart h/w */
cp_start_hw(cp); cp_start_hw(cp);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
...@@ -1348,10 +1355,11 @@ static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -1348,10 +1355,11 @@ static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
int rc; int rc;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = mii_ethtool_gset(&cp->mii_if, cmd); rc = mii_ethtool_gset(&cp->mii_if, cmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
...@@ -1360,10 +1368,11 @@ static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -1360,10 +1368,11 @@ static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
int rc; int rc;
unsigned long flags;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = mii_ethtool_sset(&cp->mii_if, cmd); rc = mii_ethtool_sset(&cp->mii_if, cmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
...@@ -1405,10 +1414,12 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data) ...@@ -1405,10 +1414,12 @@ static int cp_set_rx_csum(struct net_device *dev, u32 data)
newcmd &= ~RxChkSum; newcmd &= ~RxChkSum;
if (newcmd != cmd) { if (newcmd != cmd) {
spin_lock_irq(&cp->lock); unsigned long flags;
spin_lock_irqsave(&cp->lock, flags);
cp->cpcmd = newcmd; cp->cpcmd = newcmd;
cpw16_f(CpCmd, newcmd); cpw16_f(CpCmd, newcmd);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
return 0; return 0;
...@@ -1418,34 +1429,37 @@ static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs, ...@@ -1418,34 +1429,37 @@ static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *p) void *p)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
if (regs->len < CP_REGS_SIZE) if (regs->len < CP_REGS_SIZE)
return /* -EINVAL */; return /* -EINVAL */;
regs->version = CP_REGS_VER; regs->version = CP_REGS_VER;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
memcpy_fromio(p, cp->regs, CP_REGS_SIZE); memcpy_fromio(p, cp->regs, CP_REGS_SIZE);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
} }
static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol) static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
spin_lock_irq (&cp->lock); spin_lock_irqsave (&cp->lock, flags);
netdev_get_wol (cp, wol); netdev_get_wol (cp, wol);
spin_unlock_irq (&cp->lock); spin_unlock_irqrestore (&cp->lock, flags);
} }
static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol) static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
unsigned long flags;
int rc; int rc;
spin_lock_irq (&cp->lock); spin_lock_irqsave (&cp->lock, flags);
rc = netdev_set_wol (cp, wol); rc = netdev_set_wol (cp, wol);
spin_unlock_irq (&cp->lock); spin_unlock_irqrestore (&cp->lock, flags);
return rc; return rc;
} }
...@@ -1530,13 +1544,14 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1530,13 +1544,14 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data; struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data;
int rc; int rc;
unsigned long flags;
if (!netif_running(dev)) if (!netif_running(dev))
return -EINVAL; return -EINVAL;
spin_lock_irq(&cp->lock); spin_lock_irqsave(&cp->lock, flags);
rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL); rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL);
spin_unlock_irq(&cp->lock); spin_unlock_irqrestore(&cp->lock, flags);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment