]> err.no Git - linux-2.6/blobdiff - drivers/net/sis900.c
Merge branch 'block-dir' of git://brick.kernel.dk/data/git/linux-2.6-block
[linux-2.6] / drivers / net / sis900.c
index 127324f014de0a78d07694fe4a355b475d90f78c..1d4d88680db197cb1caa0660360db9001c140090 100644 (file)
@@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
                sis_priv->rx_skbuff[i] = skb;
                sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
                 sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
-                        skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                        skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
        }
        sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
 
@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *net_dev)
        long ioaddr = net_dev->base_addr;
        unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
        u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
+       int rx_work_limit;
 
        if (netif_msg_rx_status(sis_priv))
                printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
                       "status:0x%8.8x\n",
                       sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
+       rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
 
        while (rx_status & OWN) {
                unsigned int rx_size;
 
+               if (--rx_work_limit < 0)
+                       break;
+
                rx_size = (rx_status & DSIZE) - CRC_SIZE;
 
                if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *net_dev)
                           we are working on NULL sk_buff :-( */
                        if (sis_priv->rx_skbuff[entry] == NULL) {
                                if (netif_msg_rx_err(sis_priv))
-                                       printk(KERN_INFO "%s: NULL pointer " 
-                                               "encountered in Rx ring, skipping\n",
-                                               net_dev->name);
+                                       printk(KERN_WARNING "%s: NULL pointer " 
+                                             "encountered in Rx ring\n"
+                                             "cur_rx:%4.4d, dirty_rx:%4.4d\n",
+                                             net_dev->name, sis_priv->cur_rx,
+                                             sis_priv->dirty_rx);
                                break;
                        }
 
@@ -1770,13 +1777,14 @@ static int sis900_rx(struct net_device *net_dev)
                                sis_priv->rx_ring[entry].cmdsts = 0;
                                sis_priv->rx_ring[entry].bufptr = 0;
                                sis_priv->stats.rx_dropped++;
+                               sis_priv->cur_rx++;
                                break;
                        }
                        skb->dev = net_dev;
                        sis_priv->rx_skbuff[entry] = skb;
                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                        sis_priv->rx_ring[entry].bufptr = 
-                               pci_map_single(sis_priv->pci_dev, skb->tail
+                               pci_map_single(sis_priv->pci_dev, skb->data
                                        RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
                        sis_priv->dirty_rx++;
                }
@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *net_dev)
 
        /* refill the Rx buffer, what if the rate of refilling is slower
         * than consuming ?? */
-       for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
+       for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
                struct sk_buff *skb;
 
                entry = sis_priv->dirty_rx % NUM_RX_DESC;
@@ -1809,7 +1817,7 @@ static int sis900_rx(struct net_device *net_dev)
                        sis_priv->rx_skbuff[entry] = skb;
                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                        sis_priv->rx_ring[entry].bufptr =
-                               pci_map_single(sis_priv->pci_dev, skb->tail,
+                               pci_map_single(sis_priv->pci_dev, skb->data,
                                        RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
                }
        }