]> 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 3107aed0fb51958b01f7a860adc8d1771159adfc..1d4d88680db197cb1caa0660360db9001c140090 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/processor.h>      /* Processor type for cache alignment. */
 #include <asm/io.h>
@@ -93,8 +94,6 @@ static int sis900_debug = -1; /* Use SIS900_DEF_MSG as value */
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
-/* SiS 900 is capable of 32 bits BM DMA */
-#define SIS900_DMA_MASK 0xffffffff
 
 enum {
        SIS_900 = 0,
@@ -414,7 +413,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
        ret = pci_enable_device(pci_dev);
        if(ret) return ret;
        
-       i = pci_set_dma_mask(pci_dev, SIS900_DMA_MASK);
+       i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
        if(i){
                printk(KERN_ERR "sis900.c: architecture does not support"
                        "32bit PCI busmaster DMA\n");
@@ -1155,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);
 
@@ -1697,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)) {
@@ -1733,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;
                        }
 
@@ -1771,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++;
                }
@@ -1788,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;
@@ -1810,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);
                }
        }