PATCH for dmfe.c

From: Peter Wächtler (pwaechtler@loewe-komp.de)
Date: Thu Feb 01 2001 - 07:22:45 EST


I bought this really cheap fast ethernet card with davicom chip and noticed
that the driver was not SMP safe and my box was freezing very quickly.

I haven't found whom to send a patch (besides Linus) - someone
willing to include it in 2.4.2 ?

The following diff was made against 2.4.0-SuSE

-----------snip---------------
--- dmfe.c-orig Wed Jan 31 22:06:33 2001
+++ dmfe.c Wed Jan 31 22:37:07 2001
@@ -57,6 +57,9 @@
    Resource usage cleanups.
    Report driver version to user.

+ Peter Waechtler <pwaechtler@loewe-komp.de>:
+ added spinlocks for SMP-safety
+
    TODO

    Implement pci_driver::suspend() and pci_driver::resume()
@@ -198,6 +201,7 @@
         struct rx_desc *first_rx_desc;
         struct rx_desc *rx_insert_ptr;
         struct rx_desc *rx_ready_ptr; /* packet come pointer */
+ spinlock_t lock;
         u32 tx_packet_cnt; /* transmitted packet count */
         u32 tx_queue_cnt; /* wait to send packet count */
         u32 rx_avail_cnt; /* available rx descriptor count */
@@ -211,7 +215,7 @@
         u8 link_failed; /* Ever link failed */
         u8 wait_reset; /* Hardware failed, need to reset */
         u8 in_reset_state; /* Now driver in reset routine */
- u8 rx_error_cnt; /* recievd abnormal case count */
+ u8 rx_error_cnt; /* received abnormal case count */
         u8 dm910x_chk_mode; /* Operating mode check */
         struct timer_list timer;
         struct net_device_stats stats; /* statistic counter */
@@ -419,6 +423,7 @@
         dev->get_stats = &dmfe_get_stats;
         dev->set_multicast_list = &dmfe_set_filter_mode;
         dev->do_ioctl = &dmfe_do_ioctl;
+ spin_lock_init(&db->lock);

         /* read 64 word srom data */
         for (i = 0; i < 64; i++)
@@ -595,19 +600,22 @@
 {
         struct dmfe_board_info *db = dev->priv;
         struct tx_desc *txptr;
+ unsigned long flags;

         DMFE_DBUG(0, "dmfe_start_xmit", 0);

+ spin_lock_irqsave(&db->lock, flags);
+
         netif_stop_queue(dev);

         /* Too large packet check */
         if (skb->len > MAX_PACKET_SIZE) {
                 printk(KERN_ERR "%s: oversized frame (%d bytes) for transmit.\n",
dev->name, (u16) skb->len);
- dev_kfree_skb(skb);
- return 0;
+ goto tx_out;
         }
- /* No Tx resource check, it never happen nromally */
+ /* No Tx resource check, it never happen normally */
         if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
+ spin_unlock_irqrestore(&db->lock, flags);
                 return 1;
         }

@@ -633,8 +641,11 @@
         if (db->tx_packet_cnt < TX_FREE_DESC_CNT)
                 netif_wake_queue(dev);
 
+tx_out:
         /* free this SKB */
         dev_kfree_skb(skb);
+
+ spin_unlock_irqrestore(&db->lock,flags);
         return 0;
 }

@@ -694,6 +705,8 @@

         DMFE_DBUG(0, "dmfe_interrupt()", 0);
 
+ spin_lock(&db->lock);
+
         /* Disable all interrupt in CR7 to solve the interrupt edge problem */
         outl(0, ioaddr + DCR7);
 
@@ -709,6 +722,7 @@
                 netif_stop_queue(dev);
                 db->wait_reset = 1; /* Need to RESET */
                 outl(0, ioaddr + DCR7); /* disable all interrupt */
+ spin_unlock(&db->lock);
                 return;
         }
         /* Free the transmitted descriptor */
@@ -770,6 +784,8 @@
         else
                 db->cr7_data = 0x1a2cd;
         outl(db->cr7_data, ioaddr + DCR7);
+
+ spin_unlock(&db->lock);
 }

 /*
-----------snip---------------
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org



This archive was generated by hypermail 2b29 : Wed Feb 07 2001 - 21:00:31 EST