patch-2.4.0-test10 linux/drivers/net/wavelan.c
Next file: linux/drivers/net/wavelan.p.h
Previous file: linux/drivers/net/wan/sdlamain.c
Back to the patch index
Back to the overall index
- Lines: 231
- Date:
Thu Oct 12 14:19:32 2000
- Orig file:
v2.4.0-test9/linux/drivers/net/wavelan.c
- Orig date:
Tue Jul 18 16:09:27 2000
diff -u --recursive --new-file v2.4.0-test9/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
@@ -173,37 +173,29 @@
/*------------------------------------------------------------------*/
/*
* Disable interrupts on the WaveLAN hardware.
+ * (called by wv_82586_stop())
*/
static inline void wv_ints_off(device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
- unsigned long flags;
-
- wv_splhi(lp, &flags);
lp->hacr &= ~HACR_INTRON;
hacr_write(ioaddr, lp->hacr);
-
- wv_splx(lp, &flags);
} /* wv_ints_off */
/*------------------------------------------------------------------*/
/*
* Enable interrupts on the WaveLAN hardware.
+ * (called by wv_hw_reset())
*/
static inline void wv_ints_on(device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
- unsigned long flags;
-
- wv_splhi(lp, &flags);
lp->hacr |= HACR_INTRON;
hacr_write(ioaddr, lp->hacr);
-
- wv_splx(lp, &flags);
} /* wv_ints_on */
/******************* MODEM MANAGEMENT SUBROUTINES *******************/
@@ -871,14 +863,18 @@
static inline void wv_82586_reconfig(device * dev)
{
net_local *lp = (net_local *) dev->priv;
+ unsigned long flags;
/* Arm the flag, will be cleard in wv_82586_config() */
lp->reconfig_82586 = 1;
/* Check if we can do it now ! */
- if((netif_running(dev)) && !(netif_queue_stopped(dev)))
+ if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
+ wv_splhi(lp, &flags);
/* May fail */
wv_82586_config(dev);
+ wv_splx(lp, &flags);
+ }
else {
#ifdef DEBUG_CONFIG_INFO
printk(KERN_DEBUG
@@ -2806,6 +2802,7 @@
static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
{
net_local *lp = (net_local *) dev->priv;
+ unsigned long flags;
#ifdef DEBUG_TX_TRACE
printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
@@ -2822,7 +2819,9 @@
* we can do it now.
*/
if (lp->reconfig_82586) {
+ wv_splhi(lp, &flags);
wv_82586_config(dev);
+ wv_splx(lp, &flags);
/* Check that we can continue */
if (lp->tx_n_in_use == (NTXBLOCKS - 1))
return 1;
@@ -3369,21 +3368,17 @@
ac_ias_t ias; /* IA-setup action */
ac_mcs_t mcs; /* Multicast setup */
struct dev_mc_list *dmi;
- unsigned long flags;
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
#endif
- wv_splhi(lp, &flags);
-
/* Check nothing bad has happened */
if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
#ifdef DEBUG_CONFIG_ERROR
printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
dev->name);
#endif
- wv_splx(lp, &flags);
return;
}
@@ -3524,8 +3519,6 @@
if (lp->tx_n_in_use == (NTXBLOCKS - 1))
netif_stop_queue(dev);
- wv_splx(lp, &flags);
-
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
#endif
@@ -3535,6 +3528,7 @@
/*
* This routine, called by wavelan_close(), gracefully stops the
* WaveLAN controller (i82586).
+ * (called by wavelan_close())
*/
static inline void wv_82586_stop(device * dev)
{
@@ -3571,6 +3565,7 @@
* 3. Reset & Configure LAN controller (using wv_82586_start)
* 4. Start the LAN controller's command unit
* 5. Start the LAN controller's receive unit
+ * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
*/
static int wv_hw_reset(device * dev)
{
@@ -3676,16 +3671,18 @@
lp = (net_local *) dev->priv;
ioaddr = dev->base_addr;
-#ifdef DEBUG_INTERRUPT_ERROR
- /* Check state of our spinlock (it should be cleared) */
+#ifdef DEBUG_INTERRUPT_INFO
+ /* Check state of our spinlock */
if(spin_is_locked(&lp->spinlock))
- printk(KERN_INFO
+ printk(KERN_DEBUG
"%s: wavelan_interrupt(): spinlock is already locked !!!\n",
dev->name);
#endif
- /* Prevent reentrancy. It is safe because wv_splhi disable interrupts
- * before aquiring the spinlock */
+ /* Prevent reentrancy. We need to do that because we may have
+ * multiple interrupt handler running concurrently.
+ * It is safe because wv_splhi() disables interrupts before acquiring
+ * the spinlock. */
spin_lock(&lp->spinlock);
/* Check modem interupt */
@@ -3712,6 +3709,7 @@
"%s: wavelan_interrupt(): interrupt not coming from i82586\n",
dev->name);
#endif
+ spin_unlock (&lp->spinlock);
return;
}
@@ -3752,9 +3750,6 @@
wv_receive(dev);
}
- /* Release spinlock here so that wv_hw_reset() can grab it */
- spin_unlock (&lp->spinlock);
-
/* Check the state of the command unit. */
if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
(((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
@@ -3779,6 +3774,9 @@
wv_hw_reset(dev);
}
+ /* Release spinlock */
+ spin_unlock (&lp->spinlock);
+
#ifdef DEBUG_INTERRUPT_TRACE
printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
#endif
@@ -3806,14 +3804,13 @@
dev->name);
#endif
- wv_splhi(lp, &flags);
-
/* Check that we came here for something */
if (lp->tx_n_in_use <= 0) {
- wv_splx(lp, &flags);
return;
}
+ wv_splhi(lp, &flags);
+
/* Try to see if some buffers are not free (in case we missed
* an interrupt */
nreaped = wv_complete(dev, ioaddr, lp);
@@ -3910,6 +3907,7 @@
"%s: wavelan_open(): impossible to start the card\n",
dev->name);
#endif
+ wv_splx(lp, &flags);
return -EAGAIN;
}
wv_splx(lp, &flags);
@@ -3929,6 +3927,9 @@
*/
static int wavelan_close(device * dev)
{
+ net_local *lp = (net_local *) dev->priv;
+ unsigned long flags;
+
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
(unsigned int) dev);
@@ -3939,7 +3940,9 @@
/*
* Flush the Tx and disable Rx.
*/
+ wv_splhi(lp, &flags);
wv_82586_stop(dev);
+ wv_splx(lp, &flags);
free_irq(dev->irq, dev);
@@ -3965,7 +3968,7 @@
net_local *lp;
#ifdef DEBUG_CALLBACK_TRACE
- printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%x)\n",
+ printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
dev->name, (unsigned int) dev, ioaddr);
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)