aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fec_mpc52xx.c
diff options
context:
space:
mode:
authorDongdong Deng <dongdong.deng@windriver.com>2009-08-23 22:49:07 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-23 22:51:03 -0400
commit4871953c0ef2cafeb37bbe186d9d13dcb24fc2c5 (patch)
treee272c3a7aeb61a40f3ec807e2b4c8001ed837a7b /drivers/net/fec_mpc52xx.c
parent79b1bee888d43b14cf0c08fb8e5aa6cb161e48f8 (diff)
drivers/net: fixed drivers that support netpoll use ndo_start_xmit()
The NETPOLL API requires that interrupts remain disabled in netpoll_send_skb(). The use of "A functions set" in the NETPOLL API callbacks causes the interrupts to get enabled and can lead to kernel instability. The solution is to use "B functions set" to prevent the irqs from getting enabled while in netpoll_send_skb(). A functions set: local_irq_disable()/local_irq_enable() spin_lock_irq()/spin_unlock_irq() spin_trylock_irq()/spin_unlock_irq() B functions set: local_irq_save()/local_irq_restore() spin_lock_irqsave()/spin_unlock_irqrestore() spin_trylock_irqsave()/spin_unlock_irqrestore() Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> Acked-by: Matt Mackall <mpm@selenic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/fec_mpc52xx.c')
-rw-r--r--drivers/net/fec_mpc52xx.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index cc786333d95c..c40113f58963 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -309,6 +309,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
309{ 309{
310 struct mpc52xx_fec_priv *priv = netdev_priv(dev); 310 struct mpc52xx_fec_priv *priv = netdev_priv(dev);
311 struct bcom_fec_bd *bd; 311 struct bcom_fec_bd *bd;
312 unsigned long flags;
312 313
313 if (bcom_queue_full(priv->tx_dmatsk)) { 314 if (bcom_queue_full(priv->tx_dmatsk)) {
314 if (net_ratelimit()) 315 if (net_ratelimit())
@@ -316,7 +317,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
316 return NETDEV_TX_BUSY; 317 return NETDEV_TX_BUSY;
317 } 318 }
318 319
319 spin_lock_irq(&priv->lock); 320 spin_lock_irqsave(&priv->lock, flags);
320 dev->trans_start = jiffies; 321 dev->trans_start = jiffies;
321 322
322 bd = (struct bcom_fec_bd *) 323 bd = (struct bcom_fec_bd *)
@@ -332,7 +333,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
332 netif_stop_queue(dev); 333 netif_stop_queue(dev);
333 } 334 }
334 335
335 spin_unlock_irq(&priv->lock); 336 spin_unlock_irqrestore(&priv->lock, flags);
336 337
337 return NETDEV_TX_OK; 338 return NETDEV_TX_OK;
338} 339}