Commit f76f819d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] smc91x: more SMP locking fixes

From: Nicolas Pitre <nico@cam.org>

This fixes remaining locking problems on SMP.

Thanks to Hirokazu Takata for testing.
Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
parent d91c679f
...@@ -588,23 +588,26 @@ static void smc_hardware_send_pkt(unsigned long data) ...@@ -588,23 +588,26 @@ static void smc_hardware_send_pkt(unsigned long data)
struct net_device *dev = (struct net_device *)data; struct net_device *dev = (struct net_device *)data;
struct smc_local *lp = netdev_priv(dev); struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr; unsigned long ioaddr = dev->base_addr;
struct sk_buff *skb = lp->pending_tx_skb; struct sk_buff *skb;
unsigned int packet_no, len; unsigned int packet_no, len;
unsigned char *buf; unsigned char *buf;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__); DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
if (!smc_special_trylock(&lp->lock)) { if (!smc_special_trylock(&lp->lock)) {
netif_stop_queue(dev);
tasklet_schedule(&lp->tx_task); tasklet_schedule(&lp->tx_task);
return; return;
} }
skb = lp->pending_tx_skb;
lp->pending_tx_skb = NULL; lp->pending_tx_skb = NULL;
packet_no = SMC_GET_AR(); packet_no = SMC_GET_AR();
if (unlikely(packet_no & AR_FAILED)) { if (unlikely(packet_no & AR_FAILED)) {
printk("%s: Memory allocation failed.\n", dev->name); printk("%s: Memory allocation failed.\n", dev->name);
lp->stats.tx_errors++; lp->stats.tx_errors++;
lp->stats.tx_fifo_errors++; lp->stats.tx_fifo_errors++;
smc_special_unlock(&lp->lock);
goto done; goto done;
} }
...@@ -645,15 +648,15 @@ static void smc_hardware_send_pkt(unsigned long data) ...@@ -645,15 +648,15 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */ /* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE); SMC_SET_MMU_CMD(MC_ENQUEUE);
SMC_ACK_INT(IM_TX_EMPTY_INT); SMC_ACK_INT(IM_TX_EMPTY_INT);
SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT); smc_special_unlock(&lp->lock);
dev->trans_start = jiffies; dev->trans_start = jiffies;
lp->stats.tx_packets++; lp->stats.tx_packets++;
lp->stats.tx_bytes += len; lp->stats.tx_bytes += len;
done: smc_special_unlock(&lp->lock); SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
if (!THROTTLE_TX_PKTS) done: if (!THROTTLE_TX_PKTS)
netif_wake_queue(dev); netif_wake_queue(dev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1825,6 +1828,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr) ...@@ -1825,6 +1828,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
/* fill in some of the fields */ /* fill in some of the fields */
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
lp->version = revision_register & 0xff; lp->version = revision_register & 0xff;
spin_lock_init(&lp->lock);
/* Get the MAC address */ /* Get the MAC address */
SMC_SELECT_BANK(1); SMC_SELECT_BANK(1);
...@@ -1880,7 +1884,6 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr) ...@@ -1880,7 +1884,6 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
dev->set_multicast_list = smc_set_multicast_list; dev->set_multicast_list = smc_set_multicast_list;
dev->ethtool_ops = &smc_ethtool_ops; dev->ethtool_ops = &smc_ethtool_ops;
spin_lock_init(&lp->lock);
tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
INIT_WORK(&lp->phy_configure, smc_phy_configure, dev); INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
lp->mii.phy_id_mask = 0x1f; lp->mii.phy_id_mask = 0x1f;
......
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