===== drivers/net/sungem.c 1.71 vs edited ===== --- 1.71/drivers/net/sungem.c 2004-11-14 10:45:36 +01:00 +++ edited/drivers/net/sungem.c 2005-01-03 00:00:22 +01:00 @@ -950,6 +950,7 @@ return 0; } +/* Called with dev->queue_lock held */ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct gem *gp = dev->priv; @@ -976,8 +977,16 @@ return NETDEV_TX_LOCKED; } + /* We can now drop queue_lock since tx_lock protects us. But remember + * that queue_lock must be reacquired before we return. Moreover we + * must reacquire it before releasing tx_lock to avoid being called + * with the queue stopped. + */ + spin_unlock(&dev->queue_lock); + /* This is a hard error, log it. */ if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) { + spin_lock(&dev->queue_lock); netif_stop_queue(dev); spin_unlock_irqrestore(&gp->tx_lock, flags); printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", @@ -1066,6 +1075,7 @@ dev->name, entry, skb->len); mb(); writel(gp->tx_new, gp->regs + TXDMA_KICK); + spin_lock(&dev->queue_lock); spin_unlock_irqrestore(&gp->tx_lock, flags); dev->trans_start = jiffies;