ibmasr: remove unnecessary spin_unlock()
[safe/jmp/linux-2.6] / drivers / net / cassini.c
index 33ac2ef..f1936d5 100644 (file)
 
 #define DRV_MODULE_NAME                "cassini"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.4"
-#define DRV_MODULE_RELDATE     "1 July 2004"
+#define DRV_MODULE_VERSION     "1.6"
+#define DRV_MODULE_RELDATE     "21 May 2008"
 
 #define CAS_DEF_MSG_ENABLE       \
        (NETIF_MSG_DRV          | \
@@ -532,8 +532,7 @@ static void cas_spare_free(struct cas *cp)
        /* free spare buffers */
        INIT_LIST_HEAD(&list);
        spin_lock(&cp->rx_spare_lock);
-       list_splice(&cp->rx_spare_list, &list);
-       INIT_LIST_HEAD(&cp->rx_spare_list);
+       list_splice_init(&cp->rx_spare_list, &list);
        spin_unlock(&cp->rx_spare_lock);
        list_for_each_safe(elem, tmp, &list) {
                cas_page_free(cp, list_entry(elem, cas_page_t, list));
@@ -546,13 +545,11 @@ static void cas_spare_free(struct cas *cp)
         * lock than used everywhere else to manipulate this list.
         */
        spin_lock(&cp->rx_inuse_lock);
-       list_splice(&cp->rx_inuse_list, &list);
-       INIT_LIST_HEAD(&cp->rx_inuse_list);
+       list_splice_init(&cp->rx_inuse_list, &list);
        spin_unlock(&cp->rx_inuse_lock);
 #else
        spin_lock(&cp->rx_spare_lock);
-       list_splice(&cp->rx_inuse_list, &list);
-       INIT_LIST_HEAD(&cp->rx_inuse_list);
+       list_splice_init(&cp->rx_inuse_list, &list);
        spin_unlock(&cp->rx_spare_lock);
 #endif
        list_for_each_safe(elem, tmp, &list) {
@@ -573,13 +570,24 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags)
        /* make a local copy of the list */
        INIT_LIST_HEAD(&list);
        spin_lock(&cp->rx_inuse_lock);
-       list_splice(&cp->rx_inuse_list, &list);
-       INIT_LIST_HEAD(&cp->rx_inuse_list);
+       list_splice_init(&cp->rx_inuse_list, &list);
        spin_unlock(&cp->rx_inuse_lock);
 
        list_for_each_safe(elem, tmp, &list) {
                cas_page_t *page = list_entry(elem, cas_page_t, list);
 
+               /*
+                * With the lockless pagecache, cassini buffering scheme gets
+                * slightly less accurate: we might find that a page has an
+                * elevated reference count here, due to a speculative ref,
+                * and skip it as in-use. Ideally we would be able to reclaim
+                * it. However this would be such a rare case, it doesn't
+                * matter too much as we should pick it up the next time round.
+                *
+                * Importantly, if we find that the page has a refcount of 1
+                * here (our refcount), then we know it is definitely not inuse
+                * so we can reuse it.
+                */
                if (page_count(page->buffer) > 1)
                        continue;
 
@@ -2037,6 +2045,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
 
                skb_shinfo(skb)->nr_frags++;
                skb->data_len += hlen - swivel;
+               skb->truesize += hlen - swivel;
                skb->len      += hlen - swivel;
 
                get_page(page->buffer);
@@ -2139,9 +2148,12 @@ end_copy_pkt:
                if (addr)
                        cas_page_unmap(addr);
        }
-       skb->csum = csum_unfold(~csum);
-       skb->ip_summed = CHECKSUM_COMPLETE;
        skb->protocol = eth_type_trans(skb, cp->dev);
+       if (skb->protocol == htons(ETH_P_IP)) {
+               skb->csum = csum_unfold(~csum);
+               skb->ip_summed = CHECKSUM_COMPLETE;
+       } else
+               skb->ip_summed = CHECKSUM_NONE;
        return len;
 }
 
@@ -2585,7 +2597,7 @@ static int cas_poll(struct napi_struct *napi, int budget)
 {
        struct cas *cp = container_of(napi, struct cas, napi);
        struct net_device *dev = cp->dev;
-       int i, enable_intr, todo, credits;
+       int i, enable_intr, credits;
        u32 status = readl(cp->regs + REG_INTR_STATUS);
        unsigned long flags;
 
@@ -4349,7 +4361,7 @@ static int cas_close(struct net_device *dev)
        struct cas *cp = netdev_priv(dev);
 
 #ifdef USE_NAPI
-       napi_enable(&cp->napi);
+       napi_disable(&cp->napi);
 #endif
        /* Make sure we don't get distracted by suspend/resume */
        mutex_lock(&cp->pm_mutex);
@@ -4393,7 +4405,7 @@ static struct {
        {"tx_fifo_errors"},
        {"tx_packets"}
 };
-#define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN)
+#define CAS_NUM_STAT_KEYS ARRAY_SIZE(ethtool_cassini_statnames)
 
 static struct {
        const int offsets;      /* neg. values for 2nd arg to cas_read_phy */
@@ -5084,7 +5096,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
 
        /* give us access to cassini registers */
        cp->regs = pci_iomap(pdev, 0, casreg_len);
-       if (cp->regs == 0UL) {
+       if (!cp->regs) {
                dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
                goto err_out_free_res;
        }