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--------------- - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org