patch-2.3.43 linux/drivers/net/sis900.c
Next file: linux/drivers/net/sk98lin/h/skdrv2nd.h
Previous file: linux/drivers/net/shaper.c
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Thu Feb 10 12:26:47 2000
- Orig file:
v2.3.42/linux/drivers/net/sis900.c
- Orig date:
Tue Jan 4 13:57:17 2000
diff -u --recursive --new-file v2.3.42/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
@@ -39,6 +39,7 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
+#include <linux/init.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -112,6 +113,8 @@
struct net_device *next_module;
struct net_device_stats stats;
struct pci_dev * pci_dev;
+
+ spinlock_t lock;
struct mac_chip_info * mac;
struct mii_phy * mii;
@@ -131,15 +134,11 @@
int LinkOn;
};
-#ifdef MODULE
-#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>");
MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
MODULE_PARM(multicast_filter_limit, "i");
MODULE_PARM(max_interrupt_work, "i");
MODULE_PARM(debug, "i");
-#endif
-#endif
static int sis900_open(struct net_device *net_dev);
static int sis900_mii_probe (struct net_device * net_dev);
@@ -167,18 +166,16 @@
static struct net_device *root_sis900_dev = NULL;
/* walk through every ethernet PCI devices to see if some of them are matched with our card list*/
-int sis900_probe (struct net_device * net_dev)
+static int __init sis900_probe (void)
{
int found = 0;
struct pci_dev * pci_dev = NULL;
- if (!pci_present())
- return -ENODEV;
-
while ((pci_dev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_dev)) != NULL) {
/* pci_dev contains all ethernet devices */
u32 pci_io_base;
struct mac_chip_info * mac;
+ struct net_device *net_dev = NULL;
for (mac = mac_chip_table; mac->vendor_id; mac++) {
/* try to match our card list */
@@ -198,6 +195,7 @@
continue;
/* setup various bits in PCI command register */
+ pci_enable_device (pci_dev);
pci_set_master(pci_dev);
/* do the real low level jobs */
@@ -258,6 +256,7 @@
net_dev->irq = irq;
sis_priv->pci_dev = pci_dev;
sis_priv->mac = mac;
+ sis_priv->lock = SPIN_LOCK_UNLOCKED;
/* probe for mii transciver */
if (sis900_mii_probe(net_dev) == 0) {
@@ -277,6 +276,8 @@
net_dev->get_stats = &sis900_get_stats;
net_dev->set_multicast_list = &set_rx_mode;
net_dev->do_ioctl = &mii_ioctl;
+ net_dev->tx_timeout = sis900_tx_timeout;
+ net_dev->watchdog_timeo = TX_TIMEOUT;
return net_dev;
}
@@ -506,9 +507,7 @@
set_rx_mode(net_dev);
- net_dev->tbusy = 0;
- net_dev->interrupt = 0;
- net_dev->start = 1;
+ netif_start_queue(net_dev);
/* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
@@ -811,7 +810,8 @@
}
net_dev->trans_start = jiffies;
- net_dev->tbusy = sis_priv->tx_full = 0;
+ sis_priv->tx_full = 0;
+ netif_start_queue(net_dev);
/* FIXME: Should we restart the transmission thread here ?? */
@@ -827,13 +827,6 @@
long ioaddr = net_dev->base_addr;
unsigned int entry;
- /* test tbusy to see if we have timeout situation then set it */
- if (test_and_set_bit(0, (void*)&net_dev->tbusy) != 0) {
- if (jiffies - net_dev->trans_start > TX_TIMEOUT)
- sis900_tx_timeout(net_dev);
- return 1;
- }
-
/* Calculate the next Tx descriptor entry. */
entry = sis_priv->cur_tx % NUM_TX_DESC;
sis_priv->tx_skbuff[entry] = skb;
@@ -846,7 +839,7 @@
if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
/* Typical path, clear tbusy to indicate more
transmission is possible */
- clear_bit(0, (void*)&net_dev->tbusy);
+ netif_start_queue(net_dev);
} else {
/* no more transmit descriptor avaiable, tbusy remain set */
sis_priv->tx_full = 1;
@@ -867,26 +860,12 @@
static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
struct net_device *net_dev = (struct net_device *)dev_instance;
+ struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
int boguscnt = max_interrupt_work;
long ioaddr = net_dev->base_addr;
u32 status;
-#if defined(__i386__)
- /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
- if (test_and_set_bit(0, (void*)&net_dev->interrupt)) {
- printk(KERN_INFO "%s: SMP simultaneous entry of "
- "an interrupt handler.\n", net_dev->name);
- net_dev->interrupt = 0; /* Avoid halting machine. */
- return;
- }
-#else
- if (net_dev->interrupt) {
- printk(KERN_INFO "%s: Re-entering the interrupt handler.\n",
- net_dev->name);
- return;
- }
- net_dev->interrupt = 1;
-#endif
+ spin_lock (&sis_priv->lock);
do {
status = inl(ioaddr + isr);
@@ -923,11 +902,7 @@
"interrupt status = 0x%#8.8x.\n",
net_dev->name, inl(ioaddr + isr));
-#if defined(__i386__)
- clear_bit(0, (void*)&net_dev->interrupt);
-#else
- net_dev->interrupt = 0;
-#endif
+ spin_unlock (&sis_priv->lock);
return;
}
@@ -1079,13 +1054,12 @@
sis_priv->tx_ring[entry].cmdsts = 0;
}
- if (sis_priv->tx_full && net_dev->tbusy &&
+ if (sis_priv->tx_full && test_bit(LINK_STATE_XOFF, &net_dev->flags) &&
sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC - 4) {
/* The ring is no longer full, clear tbusy, tx_full and
schedule more transmission by marking NET_BH */
sis_priv->tx_full = 0;
- clear_bit(0, (void *)&net_dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue (net_dev);
}
}
@@ -1096,8 +1070,7 @@
struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
int i;
- net_dev->start = 0;
- net_dev->tbusy = 1;
+ netif_stop_queue(net_dev);
/* Disable interrupts by clearing the interrupt mask. */
outl(0x0000, ioaddr + imr);
@@ -1264,14 +1237,7 @@
outl(PESEL, ioaddr + cfg);
}
-#ifdef MODULE
-int init_module(void)
-{
- return sis900_probe(NULL);
-}
-
-void
-cleanup_module(void)
+static void __exit sis900_cleanup_module(void)
{
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
while (root_sis900_dev) {
@@ -1289,4 +1255,5 @@
}
}
-#endif /* MODULE */
+module_init(sis900_probe);
+module_exit(sis900_cleanup_module);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)