Hey Jeff,

I know you're backlogged, but if you could consider pulling from branch
'for-jeff' at git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6.git
I'd appreciate it a lot.

The content is described below. It merges fine with your 'upstream-fixes'
branch.

Francois Romieu
    8139too: fix a TX timeout watchdog thread against NAPI softirq race
    
    Ingo's stealth lock validator detected that both thread acquire
    dev->xmit_lock and tp->rx_lock in reverse order.
    
    Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>

Alexey Dobriyan
    dscc4: fix dscc4_init_dummy_skb check
    
    It returns a pointer.
    
    Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]>
    Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>

Andy Gospodarek
    r8169: fix forced-mode link settings
    
    Allow the r8169 driver to set devices to be full-duplex only when
    auto-negotiate is disabled.
    
    Signed-off-by: Andy Gospodarek <[EMAIL PROTECTED]>
    Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>

Francois Romieu <[EMAIL PROTECTED]>
    r8169: prevent excessive busy-waiting
    
    The MII registers read/write function blindly busy waits for an
    amount of 1000 us (1 ms), then up to 200 ms. These functions are
    called from irq disabled context. Depending on the clock management,
    it triggers lost ticks events. Since the value is way above the
    standard delay required for mii register access, it strangely looks
    like a bandaid against posted writes.
    
    Fixes http://bugzilla.kernel.org/show_bug.cgi?id=5947
    
    Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>

diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index adfba44..2beac55 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -586,6 +586,7 @@ struct rtl8139_private {
        dma_addr_t tx_bufs_dma;
        signed char phys[4];            /* MII device addresses. */
        char twistie, twist_row, twist_col;     /* Twister tune state. */
+       unsigned int watchdog_fired : 1;
        unsigned int default_port : 4;  /* Last dev->if_port value. */
        unsigned int have_thread : 1;
        spinlock_t lock;
@@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct 
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
 static void rtl8139_thread (void *_data);
+static void rtl8139_tx_timeout_task(void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data)
 {
        struct net_device *dev = _data;
        struct rtl8139_private *tp = netdev_priv(dev);
-       unsigned long thr_delay;
+       unsigned long thr_delay = next_tick;
 
-       if (rtnl_shlock_nowait() == 0) {
+       if (tp->watchdog_fired) {
+               tp->watchdog_fired = 0;
+               rtl8139_tx_timeout_task(_data);
+       } else if (rtnl_shlock_nowait() == 0) {
                rtl8139_thread_iter (dev, tp, tp->mmio_addr);
                rtnl_unlock ();
-
-               thr_delay = next_tick;
        } else {
                /* unlikely race.  mitigate with fast poll. */
                thr_delay = HZ / 2;
@@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct r
        if (tp->have_thread) {
                cancel_rearming_delayed_work(&tp->thread);
                tp->have_thread = 0;
-       }
+       } else
+               flush_scheduled_work();
 }
 
 static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
@@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (str
        /* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
-
-static void rtl8139_tx_timeout (struct net_device *dev)
+static void rtl8139_tx_timeout_task (void *_data)
 {
+       struct net_device *dev = _data;
        struct rtl8139_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        int i;
        u8 tmp8;
-       unsigned long flags;
 
        printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
                "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
@@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct n
        if (tmp8 & CmdTxEnb)
                RTL_W8 (ChipCmd, CmdRxEnb);
 
-       spin_lock(&tp->rx_lock);
+       spin_lock_bh(&tp->rx_lock);
        /* Disable interrupts by clearing the interrupt mask. */
        RTL_W16 (IntrMask, 0x0000);
 
        /* Stop a shared interrupt from scavenging while we are. */
-       spin_lock_irqsave (&tp->lock, flags);
+       spin_lock_irq(&tp->lock);
        rtl8139_tx_clear (tp);
-       spin_unlock_irqrestore (&tp->lock, flags);
+       spin_unlock_irq(&tp->lock);
 
        /* ...and finally, reset everything */
        if (netif_running(dev)) {
                rtl8139_hw_start (dev);
                netif_wake_queue (dev);
        }
-       spin_unlock(&tp->rx_lock);
+       spin_unlock_bh(&tp->rx_lock);
 }
 
+static void rtl8139_tx_timeout (struct net_device *dev)
+{
+       struct rtl8139_private *tp = netdev_priv(dev);
+
+       if (!tp->have_thread) {
+               INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
+               schedule_delayed_work(&tp->thread, next_tick);
+       } else
+               tp->watchdog_fired = 1;
+
+}
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2e1bed1..6e10184 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioa
        int i;
 
        RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed writing to the specified 
MII register */
                if (!(RTL_R32(PHYAR) & 0x80000000)) 
                        break;
-               udelay(100);
+               udelay(25);
        }
 }
 
@@ -499,15 +498,14 @@ static int mdio_read(void __iomem *ioadd
        int i, value = -1;
 
        RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed retrieving data from the 
specified MII register */
                if (RTL_R32(PHYAR) & 0x80000000) {
                        value = (int) (RTL_R32(PHYAR) & 0xFFFF);
                        break;
                }
-               udelay(100);
+               udelay(25);
        }
        return value;
 }
@@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct
 
                if (duplex == DUPLEX_HALF)
                        auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
+
+               if (duplex == DUPLEX_FULL)
+                       auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
        }
 
        tp->phy_auto_nego_reg = auto_nego;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 2f61a47..1ff5de0 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -1943,7 +1943,7 @@ static int dscc4_init_ring(struct net_de
                                        (++i%TX_RING_SIZE)*sizeof(*tx_fd));
        } while (i < TX_RING_SIZE);
 
-       if (dscc4_init_dummy_skb(dpriv) < 0)
+       if (!dscc4_init_dummy_skb(dpriv))
                goto err_free_dma_tx;
 
        memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE);
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to